import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from '../../theme';

jest.mock('next-intl', () => ({
  useLocale: () => 'en',
}));

import RatingInput, { RatingInputProps } from './RatingInput';

function renderRating(props: Partial<RatingInputProps> = {}) {
  const onChange = jest.fn();
  const utils = render(
    <ThemeProvider>
      <RatingInput value={0} onChange={onChange} {...props} />
    </ThemeProvider>,
  );
  return { ...utils, onChange };
}

describe('<RatingInput/> component', () => {
  it('renders max stars and exposes the current value', () => {
    const { container } = renderRating({ value: 3 });
    expect(container.querySelector('[data-rating="3"]')).toBeInTheDocument();
    expect(container.querySelectorAll('[data-star]')).toHaveLength(5);
  });

  it('calls onChange with the clicked star value', async () => {
    const user = userEvent.setup();
    const { onChange } = renderRating({ value: 0 });
    await user.click(screen.getByRole('radio', { name: '4' }));
    expect(onChange).toHaveBeenCalledWith(4);
  });

  it('reflects the chosen value on the matching star', () => {
    renderRating({ value: 2 });
    expect(screen.getByRole('radio', { name: '2' })).toHaveAttribute('aria-checked', 'true');
    expect(screen.getByRole('radio', { name: '3' })).toHaveAttribute('aria-checked', 'false');
  });

  it('is a non-interactive display with no radios when readOnly', () => {
    const { container, onChange } = renderRating({ value: 5, readOnly: true });
    expect(container.querySelector('[data-rating="5"]')).toBeInTheDocument();
    expect(container.querySelectorAll('[data-star]')).toHaveLength(0);
    expect(screen.queryByRole('radio')).not.toBeInTheDocument();
    expect(onChange).not.toHaveBeenCalled();
  });

  it('renders a fractional average honestly instead of rounding it', () => {
    const { container } = renderRating({ value: 4.5, readOnly: true });
    const fractions = Array.from(container.querySelectorAll('[data-star-fraction]')).map((el) =>
      Number(el.getAttribute('data-star-fraction')),
    );
    expect(fractions).toEqual([1, 1, 1, 1, 0.5]);
  });

  it('renders full/empty fractions (1 or 0) for a whole-number average', () => {
    const { container } = renderRating({ value: 3, readOnly: true });
    const fractions = Array.from(container.querySelectorAll('[data-star-fraction]')).map((el) =>
      Number(el.getAttribute('data-star-fraction')),
    );
    expect(fractions).toEqual([1, 1, 1, 0, 0]);
  });
});
