/**
 * Tests for the LassoLayerFiltersUI dialog — renders layer checkboxes from the
 * committed selection, edits a draft, commits only on Apply (Cancel/close
 * discards), supports "All selected" and search.
 */
import { describe, it, expect, vi } from 'vitest'
import { render, fireEvent, screen, within } from '@testing-library/react'
import { LassoLayerFiltersUI } from './layer-filters'

const layers = [
  { id: 'a', label: 'Blocks', checked: true },
  { id: 'b', label: 'Roads', checked: false },
]

function setup(props: Partial<Parameters<typeof LassoLayerFiltersUI>[0]> = {}) {
  const handlers = { onClose: vi.fn(), onApply: vi.fn() }
  render(<LassoLayerFiltersUI open layers={layers} {...handlers} {...props} />)
  return handlers
}

const dialog = () => screen.getByRole('dialog')

describe('LassoLayerFiltersUI', () => {
  it('renders the title and a checkbox per layer (+ All selected)', () => {
    setup()
    expect(screen.getByText('Layer Filters')).toBeDefined()
    // 2 layers + the "All selected" master = 3 checkboxes.
    expect(within(dialog()).getAllByRole('checkbox')).toHaveLength(3)
  })

  it('reflects the committed selection in the draft', () => {
    setup()
    expect(
      within(dialog()).getByRole<HTMLInputElement>('checkbox', {
        name: 'Blocks',
      }).checked,
    ).toBe(true)
    expect(
      within(dialog()).getByRole<HTMLInputElement>('checkbox', {
        name: 'Roads',
      }).checked,
    ).toBe(false)
  })

  it('commits the edited selection only on Apply', () => {
    const { onApply, onClose } = setup()
    fireEvent.click(within(dialog()).getByRole('checkbox', { name: 'Roads' }))
    // Not committed yet.
    expect(onApply).not.toHaveBeenCalled()
    fireEvent.click(screen.getByRole('button', { name: 'Apply' }))
    expect(onApply).toHaveBeenCalledWith(['a', 'b'])
    expect(onClose).toHaveBeenCalled()
  })

  it('discards the draft on Cancel', () => {
    const { onApply, onClose } = setup()
    fireEvent.click(within(dialog()).getByRole('checkbox', { name: 'Blocks' }))
    fireEvent.click(screen.getByRole('button', { name: 'Cancel' }))
    expect(onApply).not.toHaveBeenCalled()
    expect(onClose).toHaveBeenCalled()
  })

  it('"All selected" toggles every layer', () => {
    const { onApply } = setup()
    // Currently only "Blocks" checked → master is indeterminate; clicking selects all.
    fireEvent.click(
      within(dialog()).getByRole('checkbox', { name: 'All selected' }),
    )
    fireEvent.click(screen.getByRole('button', { name: 'Apply' }))
    expect(onApply).toHaveBeenCalledWith(['a', 'b'])
  })

  it('filters the list by search text', () => {
    setup()
    fireEvent.change(within(dialog()).getByRole('textbox'), {
      target: { value: 'road' },
    })
    expect(
      within(dialog()).queryByRole('checkbox', { name: 'Blocks' }),
    ).toBeNull()
    expect(
      within(dialog()).getByRole('checkbox', { name: 'Roads' }),
    ).toBeDefined()
  })

  it('hides "All selected" while searching', () => {
    setup()
    expect(
      within(dialog()).getByRole('checkbox', { name: 'All selected' }),
    ).toBeDefined()
    fireEvent.change(within(dialog()).getByRole('textbox'), {
      target: { value: 'road' },
    })
    expect(
      within(dialog()).queryByRole('checkbox', { name: 'All selected' }),
    ).toBeNull()
  })

  it('does not render when closed', () => {
    setup({ open: false })
    expect(screen.queryByRole('dialog')).toBeNull()
  })
})
