import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { I18nProvider } from '../i18n'
import { SampleCapture, type Modality } from './SampleCapture'

function renderSC(modality: Modality, onChange = vi.fn(), demoSample?: string) {
  render(
    <I18nProvider initial="en">
      <SampleCapture modality={modality} id="s" value={null} onChange={onChange} demoSample={demoSample} />
    </I18nProvider>,
  )
  return onChange
}

describe('SampleCapture', () => {
  beforeEach(() => vi.restoreAllMocks())

  it('fingerprint shows the honest "image upload, not sensor" note', () => {
    renderSC('fingerprint')
    expect(screen.getByText(/cannot read your device fingerprint sensor/i)).toBeInTheDocument()
  })

  it('upload validates + emits a data URI', async () => {
    const onChange = renderSC('fingerprint')
    const input = document.querySelector('input[type=file]') as HTMLInputElement
    const file = new File(['x'], 'fp.png', { type: 'image/png' })
    fireEvent.change(input, { target: { files: [file] } })
    await waitFor(() => expect(onChange).toHaveBeenCalled())
    expect(String(onChange.mock.calls[0][0])).toMatch(/^data:/)
  })

  it('rejects a non-image upload for an image slot', async () => {
    const onChange = renderSC('fingerprint')
    const input = document.querySelector('input[type=file]') as HTMLInputElement
    fireEvent.change(input, { target: { files: [new File(['x'], 'a.wav', { type: 'audio/wav' })] } })
    await screen.findByText(/choose an image file/i)
    expect(onChange).not.toHaveBeenCalled()
  })

  it('"Use demo sample" emits the provided sample', () => {
    const onChange = renderSC('fingerprint', vi.fn(), 'BASE64SAMPLE')
    fireEvent.click(screen.getByRole('button', { name: 'Use demo sample' }))
    expect(onChange).toHaveBeenCalledWith('BASE64SAMPLE')
  })

  it('face camera permission denied shows guidance', async () => {
    Object.defineProperty(navigator, 'mediaDevices', {
      configurable: true,
      value: { getUserMedia: vi.fn().mockRejectedValue(Object.assign(new Error('no'), { name: 'NotAllowedError' })) },
    })
    renderSC('face')
    fireEvent.click(screen.getByRole('button', { name: 'Use camera' }))
    await screen.findByText(/Camera permission denied/i)
  })
})
