import { render } from 'vitest-browser-react'
import {
  FileTree,
  FileTreeFile,
  FileTreeFolder,
  FileTreeFolderPanel,
  FileTreeFolderTrigger,
  FileTreeIcon,
  FileTreeLabel,
  FileTreeList,
} from '../index'

function TestFileTree({ onPreview = vi.fn() }: { onPreview?: (itemId: string) => void }) {
  return (
    <FileTree aria-label="Project files">
      <FileTreeList>
        <FileTreeFolder defaultOpen>
          <FileTreeFolderTrigger>
            <FileTreeIcon type="folder" />
            <FileTreeLabel>src</FileTreeLabel>
          </FileTreeFolderTrigger>
          <FileTreeFolderPanel>
            <FileTreeFolder defaultOpen>
              <FileTreeFolderTrigger>
                <FileTreeIcon type="folder" />
                <FileTreeLabel>components</FileTreeLabel>
              </FileTreeFolderTrigger>
              <FileTreeFolderPanel>
                <FileTreeFile selected onClick={() => onPreview('button')}>
                  <FileTreeIcon type="code" />
                  <FileTreeLabel>button.tsx</FileTreeLabel>
                </FileTreeFile>
                <FileTreeFile onClick={() => onPreview('readme')}>
                  <FileTreeIcon type="markdown" />
                  <FileTreeLabel>README.md</FileTreeLabel>
                </FileTreeFile>
              </FileTreeFolderPanel>
            </FileTreeFolder>
            <FileTreeFile onClick={() => onPreview('index')}>
              <FileTreeIcon type="code" />
              <FileTreeLabel>index.ts</FileTreeLabel>
            </FileTreeFile>
          </FileTreeFolderPanel>
        </FileTreeFolder>
        <FileTreeFile onClick={() => onPreview('package')}>
          <FileTreeIcon type="json" />
          <FileTreeLabel>package.json</FileTreeLabel>
        </FileTreeFile>
      </FileTreeList>
    </FileTree>
  )
}

describe('FileTree', () => {
  it('renders a labelled disclosure list instead of an ARIA treeview', async () => {
    const screen = await render(<TestFileTree />)
    const root = screen.getByLabelText('Project files')
    const src = screen.getByRole('button', { name: 'src' })
    const selectedFile = screen.getByRole('button', { name: 'button.tsx' })

    await expect.element(root).not.toHaveAttribute('role', 'tree')
    await expect.element(src).toHaveAttribute('aria-expanded', 'true')
    await expect.element(src).toHaveAttribute('aria-controls')
    await expect.element(src).not.toHaveAttribute('aria-current')
    await expect.element(src).not.toHaveAttribute('data-selected')
    await expect.element(selectedFile).toHaveAttribute('aria-current', 'true')
    await expect.element(selectedFile).toHaveAttribute('data-selected')
  })

  it('activates file preview buttons without navigation semantics', async () => {
    const onPreview = vi.fn()
    const screen = await render(<TestFileTree onPreview={onPreview} />)

    await screen.getByRole('button', { name: 'README.md' }).click()

    expect(onPreview).toHaveBeenCalledWith('readme')
    await expect
      .element(screen.getByRole('button', { name: 'README.md' }))
      .not.toHaveAttribute('href')
  })

  it('does not activate disabled file buttons', async () => {
    const screen = await render(
      <FileTree aria-label="Disabled files">
        <FileTreeList>
          <FileTreeFile disabled>
            <FileTreeIcon type="file" />
            <FileTreeLabel>disabled.txt</FileTreeLabel>
          </FileTreeFile>
        </FileTreeList>
      </FileTree>,
    )

    await expect.element(screen.getByRole('button', { name: 'disabled.txt' })).toBeDisabled()
    await expect
      .element(screen.getByRole('button', { name: 'disabled.txt' }))
      .toHaveAttribute('data-disabled')
  })

  it('resolves disabled folder triggers through the collapsible state', async () => {
    const screen = await render(
      <FileTree aria-label="Disabled folders">
        <FileTreeList>
          <FileTreeFolder disabled defaultOpen>
            <FileTreeFolderTrigger>
              <FileTreeIcon type="folder" />
              <FileTreeLabel>locked</FileTreeLabel>
            </FileTreeFolderTrigger>
            <FileTreeFolderPanel>
              <FileTreeFile>
                <FileTreeIcon type="file" />
                <FileTreeLabel>nested.txt</FileTreeLabel>
              </FileTreeFile>
            </FileTreeFolderPanel>
          </FileTreeFolder>
        </FileTreeList>
      </FileTree>,
    )
    const trigger = screen.getByRole('button', { name: 'locked' })

    await expect.element(trigger).toHaveAttribute('aria-disabled', 'true')
    await expect.element(trigger).toHaveAttribute('aria-expanded', 'true')
  })
})
