import { render, screen, fireEvent } from '@testing-library/react'
import { SlideCanvas } from '../slide-deck/SlideCanvas'
import { SlideFilmstrip } from '../slide-deck/SlideFilmstrip'
import { SlideDeckViewer } from '../slide-deck/SlideDeckViewer'
import type { SlideData } from '../slide-deck/types'

const slides: SlideData[] = [
  { id: 's1', slideNumber: 1, title: 'Title', imageUrl: 'https://x/1.png', status: 'ready' },
  { id: 's2', slideNumber: 2, title: 'Problem', imageUrl: 'https://x/2.png', status: 'ready' },
  { id: 's3', slideNumber: 3, title: 'Solution', status: 'generating' },
]

describe('SlideCanvas', () => {
  it('renders a full-bleed image in image render mode', () => {
    render(<SlideCanvas slide={slides[0]} />)
    const img = screen.getByRole('img')
    expect(img).toHaveAttribute('src', 'https://x/1.png')
  })

  it('shows a generating state while the slide is in progress', () => {
    const { container } = render(<SlideCanvas slide={slides[2]} />)
    const el = container.querySelector('[data-status="generating"]')
    expect(el).toBeInTheDocument()
    expect(el).toHaveAttribute('aria-busy', 'true')
  })

  it('shows an error state with a retry control', () => {
    const onRetry = jest.fn()
    render(<SlideCanvas slide={{ id: 'e', slideNumber: 1, status: 'error' }} onRetry={onRetry} />)
    const retry = screen.getByRole('button', { name: /retry|regenerate/i })
    fireEvent.click(retry)
    expect(onRetry).toHaveBeenCalled()
  })
})

describe('SlideFilmstrip', () => {
  it('renders a thumbnail per slide and marks the active one', () => {
    render(<SlideFilmstrip slides={slides} activeId="s2" onSelect={() => {}} />)
    const thumbs = screen.getAllByRole('button')
    expect(thumbs).toHaveLength(3)
    const active = thumbs.find((t) => t.getAttribute('aria-current') === 'true')
    expect(active).toBeTruthy()
  })

  it('calls onSelect with the slide id when a thumbnail is clicked', () => {
    const onSelect = jest.fn()
    render(<SlideFilmstrip slides={slides} activeId="s1" onSelect={onSelect} />)
    fireEvent.click(screen.getAllByRole('button')[2])
    expect(onSelect).toHaveBeenCalledWith('s3')
  })
})

describe('SlideDeckViewer', () => {
  it('renders the active slide and the position indicator', () => {
    const { container } = render(<SlideDeckViewer slides={slides} activeId="s2" />)
    expect(screen.getByText('2 / 3')).toBeInTheDocument()
    const stage = container.querySelector('[data-testid="slide-deck-stage"]') as HTMLElement
    expect(stage.querySelector('img')).toHaveAttribute('src', 'https://x/2.png')
  })

  it('advances the active slide with ArrowRight', () => {
    const onActiveChange = jest.fn()
    const { container } = render(
      <SlideDeckViewer slides={slides} activeId="s1" onActiveChange={onActiveChange} />
    )
    const stage = container.querySelector('[data-testid="slide-deck-stage"]') as HTMLElement
    fireEvent.keyDown(stage, { key: 'ArrowRight' })
    expect(onActiveChange).toHaveBeenCalledWith('s2')
  })

  it('renders an empty state when there are no slides', () => {
    render(<SlideDeckViewer slides={[]} emptyState={<div>No slides yet</div>} />)
    expect(screen.getByText('No slides yet')).toBeInTheDocument()
  })

  it('invokes onRegenerate for the active slide', () => {
    const onRegenerate = jest.fn()
    render(<SlideDeckViewer slides={slides} activeId="s1" onRegenerate={onRegenerate} />)
    fireEvent.click(screen.getByRole('button', { name: /regenerate/i }))
    expect(onRegenerate).toHaveBeenCalledWith(slides[0])
  })
})
