import { describe, it, expect, vi, beforeAll } from 'vitest';
import { render, screen } from '@testing-library/react';
import QuizAnswers from '@/Components/quiz/QuizAnswers';

type Props = React.ComponentProps<typeof QuizAnswers>;

const answers: Props['answers'] = [
  { text: 'Kikotu feels a surge of rage.', is_correct: true, letter: 'A', original_index: 0 },
  { text: 'Kikotu repositions his shield.', is_correct: false, letter: 'B', original_index: 1 },
];

function renderAnswers(overrides: Partial<Props> = {}) {
  return render(
    <QuizAnswers
      answers={answers}
      answerStates={{ '7-A': 'correct', '7-B': 'incorrect' }}
      answersLoading={false}
      highlightedAnswer={null}
      showCorrectFeedback={false}
      questionId={7}
      currentQuestionIndex={0}
      onAnswerSelect={vi.fn()}
      pendingAnswerKey={null}
      hasExplanationAudio={() => true}
      {...overrides}
    />
  );
}

beforeAll(() => {
  // jsdom implements no matchMedia, and both reclaimCorrectLabelHover and
  // framer-motion's reduced-motion check call it on mount.
  window.matchMedia ??= ((query: string) => ({
    matches: false,
    media: query,
    onchange: null,
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    addListener: vi.fn(),
    removeListener: vi.fn(),
    dispatchEvent: vi.fn(),
  })) as never;
});

describe('QuizAnswers feedback labels', () => {
  // Regression for ENG-2038. `Correct!` shipped clickable but with no hover or
  // active colour, so the only cue that it replays the explanation clip was the
  // cursor. `Incorrect.` had the states from the start.
  it('gives the Correct! label hover and active colours when it replays audio', () => {
    renderAnswers();

    expect(screen.getByText('Correct!')).toHaveClass(
      'cursor-pointer',
      'transition-colors',
      'duration-150',
      'hover:text-[#FFFFFFBF]',
      'active:text-[#FFFFFF]'
    );
  });

  it('keeps the Incorrect. label hover and active colours', () => {
    renderAnswers();

    expect(screen.getByText('Incorrect.')).toHaveClass(
      'cursor-pointer',
      'transition-colors',
      'duration-150',
      'hover:text-[#FFFFFF80]',
      'active:text-[#FFFFFFBF]'
    );
  });

  // The interactive treatment is per answer, not per question: an answer with no
  // explanation clip keeps the plain label — no pointer, no hover, no click.
  it('leaves both labels inert when the answer has no explanation audio', () => {
    renderAnswers({ hasExplanationAudio: () => false });

    for (const label of ['Correct!', 'Incorrect.']) {
      const node = screen.getByText(label);
      expect(node).not.toHaveClass('cursor-pointer');
      expect(node.className).not.toMatch(/hover:|active:/);
    }
  });
});
