import { describe, expect, it } from 'vitest'

import { fireEvent, renderWithProviders, screen } from '../../../test/utils'

import { useCarousel } from './useCarousel'

const Harness = ({
  open,
  length,
  initialIndex = 0,
}: {
  open: boolean
  length: number
  initialIndex?: number
}) => {
  const { index, prev, next } = useCarousel({ open, length, initialIndex })
  return (
    <div>
      <span data-testid="index">{index}</span>
      <button type="button" onClick={prev}>
        Prev
      </button>
      <button type="button" onClick={next}>
        Next
      </button>
    </div>
  )
}

describe('useCarousel', () => {
  it('clamps initial index, wraps, and resets on reopen', () => {
    const { rerender } = renderWithProviders(
      <Harness open length={3} initialIndex={99} />
    )
    expect(screen.getByTestId('index')).toHaveTextContent('2')
    fireEvent.click(screen.getByRole('button', { name: 'Next' }))
    expect(screen.getByTestId('index')).toHaveTextContent('0')
    fireEvent.click(screen.getByRole('button', { name: 'Prev' }))
    expect(screen.getByTestId('index')).toHaveTextContent('2')
    rerender(<Harness open={false} length={3} initialIndex={1} />)
    rerender(<Harness open length={3} initialIndex={1} />)
    expect(screen.getByTestId('index')).toHaveTextContent('1')
  })

  it('handles arrows only when open with multiple items', () => {
    const { rerender } = renderWithProviders(
      <Harness open length={2} initialIndex={0} />
    )
    const right = fireEvent.keyDown(window, { key: 'ArrowRight' })
    expect(screen.getByTestId('index')).toHaveTextContent('1')
    expect(right).toBe(false)
    for (const tagName of ['video', 'audio'] as const) {
      const media = document.createElement(tagName)
      media.tabIndex = 0
      document.body.appendChild(media)
      media.focus()
      fireEvent.keyDown(window, { key: 'ArrowLeft' })
      expect(screen.getByTestId('index')).toHaveTextContent('1')
      media.remove()
    }
    rerender(<Harness open length={1} />)
    fireEvent.keyDown(window, { key: 'ArrowRight' })
    expect(screen.getByTestId('index')).toHaveTextContent('0')
    rerender(<Harness open={false} length={2} />)
    fireEvent.keyDown(window, { key: 'ArrowRight' })
    expect(screen.getByTestId('index')).toHaveTextContent('0')
  })
})
