import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { useState } from 'react';
import { StarPicker } from '../star-picker';

function Controlled({ initial = null, onChangeSpy }: { initial?: number | null; onChangeSpy?: (n: number) => void }) {
  const [value, setValue] = useState<number | null>(initial);
  return (
    <StarPicker
      value={value}
      onChange={(n) => {
        setValue(n);
        onChangeSpy?.(n);
      }}
    />
  );
}

describe('StarPicker', () => {
  it('renders 5 star buttons with aria-labels', () => {
    render(<StarPicker value={null} onChange={() => {}} />);
    expect(screen.getByRole('button', { name: '1 star' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '2 stars' })).toBeInTheDocument();
    expect(screen.getByRole('button', { name: '5 stars' })).toBeInTheDocument();
  });

  it('clicking a star calls onChange with that value', () => {
    const spy = vi.fn();
    render(<StarPicker value={null} onChange={spy} />);
    fireEvent.click(screen.getByRole('button', { name: '4 stars' }));
    expect(spy).toHaveBeenCalledWith(4);
  });

  it('shows hover preview state on mouseenter', () => {
    render(<Controlled />);
    const third = screen.getByRole('button', { name: '3 stars' });
    fireEvent.mouseEnter(third);
    // Hover should fill stars 1-3 with amber, leaving 4-5 slate.
    const buttons = screen.getAllByRole('button');
    expect(buttons[0].className).toMatch(/text-amber-500/);
    expect(buttons[2].className).toMatch(/text-amber-500/);
    expect(buttons[3].className).not.toMatch(/text-amber-500/);
  });

  it('renders read-only mode without buttons', () => {
    render(<StarPicker value={4} readOnly />);
    expect(screen.queryAllByRole('button')).toHaveLength(0);
    expect(screen.getByRole('img', { name: /4 out of 5 stars/i })).toBeInTheDocument();
  });

  it('respects disabled prop', () => {
    render(<StarPicker value={null} onChange={() => {}} disabled />);
    screen.getAllByRole('button').forEach((b) => {
      expect(b).toBeDisabled();
    });
  });
});
