import { describe, expect, it, vi } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import { PalettePicker, type PaletteOption } from './PalettePicker'

const options: PaletteOption[] = [
  {
    id: 'default',
    label: 'Default',
    swatches: ['#ffffff', '#f7f7f7', '#3b5bdb', '#1a1a1a'],
    preview: {
      bg: '#ffffff', surface: '#f7f7f7', fg: '#1a1a1a', fgMuted: '#555555',
      accent: '#3b5bdb', accentFg: '#ffffff', border: '#e2e2e2',
    },
  },
  {
    id: 'slate',
    label: 'Slate',
    swatches: ['#ffffff', '#f8fafc', '#0f766e', '#0f172a'],
    preview: {
      bg: '#ffffff', surface: '#f8fafc', fg: '#0f172a', fgMuted: '#475569',
      accent: '#0f766e', accentFg: '#ffffff', border: '#e2e8f0',
    },
  },
]

describe('PalettePicker', () => {
  it('exposes a radiogroup with one aria-labelled radio per option and forwards aria-labelledby', () => {
    render(<PalettePicker options={options} onChange={() => {}} aria-labelledby="lbl" />)
    expect(screen.getByRole('radiogroup')).toBeTruthy()
    expect(screen.getByRole('radiogroup').getAttribute('aria-labelledby')).toBe('lbl')
    expect(screen.getAllByRole('radio')).toHaveLength(2)
    expect(screen.getByRole('radio', { name: 'Default' })).toBeTruthy()
    expect(screen.getByRole('radio', { name: 'Slate' })).toBeTruthy()
  })

  it('fires onChange with the selected option id', () => {
    const onChange = vi.fn()
    render(<PalettePicker options={options} value="default" onChange={onChange} aria-label="Palette" />)
    fireEvent.click(screen.getByRole('radio', { name: 'Slate' }))
    expect(onChange).toHaveBeenCalledWith('slate')
  })

  it('renders the live preview card reflecting the SELECTED option colors (not options[0])', () => {
    const { container } = render(
      <PalettePicker options={options} value="slate" onChange={() => {}} aria-label="Palette" />,
    )
    const card = container.querySelector('[data-testid="palette-preview"]') as HTMLElement
    expect(card).toBeTruthy()
    expect(card.style.getPropertyValue('--pp-bg')).toBe('#ffffff')
    expect(card.style.getPropertyValue('--pp-accent')).toBe('#0f766e')
    expect(card.getAttribute('aria-hidden')).toBe('true')
  })

  it('falls back to options[0] for the preview when value matches no option, without throwing', () => {
    const { container } = render(
      <PalettePicker options={options} value="does-not-exist" onChange={() => {}} aria-label="Palette" />,
    )
    const card = container.querySelector('[data-testid="palette-preview"]') as HTMLElement
    expect(card.style.getPropertyValue('--pp-accent')).toBe('#3b5bdb')
  })

  it('renders nothing for empty options and does not throw', () => {
    const { container } = render(<PalettePicker options={[]} onChange={() => {}} aria-label="Palette" />)
    expect(container.querySelector('[role="radiogroup"]')).toBeNull()
    expect(container.querySelector('[data-testid="palette-preview"]')).toBeNull()
  })
})