import { render, screen } from '@testing-library/react';

import { CompareOfsted } from '@/components/compare/CompareOfsted';
import type { ComparisonData, OfstedInspection, School } from '@/lib/types';

function school(urn: number, name: string): School {
  return { urn, school_name: name } as School;
}

function ofsted(partial: Partial<OfstedInspection>): OfstedInspection {
  return {
    framework: null,
    inspection_date: '2021-10-07',
    inspection_type: null,
    overall_effectiveness: null,
    quality_of_education: null,
    behaviour_attitudes: null,
    personal_development: null,
    leadership_management: null,
    early_years_provision: null,
    previous_overall: null,
    rc_safeguarding_met: null,
    rc_inclusion: null,
    rc_curriculum_teaching: null,
    rc_achievement: null,
    rc_attendance_behaviour: null,
    rc_personal_development: null,
    rc_leadership_governance: null,
    rc_early_years: null,
    rc_sixth_form: null,
    ofsted_page_url: 'https://reports.ofsted.gov.uk/provider/21/1',
    ...partial,
  };
}

const schools = [school(1, 'Graded School'), school(2, 'Carried School'), school(3, 'Card School')];

const data: Record<string, ComparisonData> = {
  '1': {
    school_info: schools[0],
    yearly_data: [],
    ofsted: ofsted({ overall_effectiveness: 1, grade_source: 'graded' }),
  },
  '2': {
    school_info: schools[1],
    yearly_data: [],
    ofsted: ofsted({ overall_effectiveness: 2, grade_source: 'ungraded_carried_forward' }),
  },
  '3': {
    school_info: schools[2],
    yearly_data: [],
    ofsted: ofsted({
      inspection_date: '2025-11-14',
      rc_safeguarding_met: true,
      report_card: {
        rc_achievement: { code: 2, label: 'Strong standard' },
        rc_attendance_behaviour: { code: 4, label: 'Needs attention' },
      },
    }),
  },
};

describe('CompareOfsted', () => {
  it('renders the three regimes without inventing an overall grade for report cards', () => {
    render(<CompareOfsted schools={schools} data={data} />);

    expect(screen.getByText('Outstanding')).toBeInTheDocument();
    // Carried-forward grade is shown but marked as such
    expect(screen.getByText('Good')).toBeInTheDocument();
    expect(screen.getByText(/carried forward/i)).toBeInTheDocument();
    // Report card: label present, no overall-grade badge for that school
    expect(screen.getByText('Report card')).toBeInTheDocument();
    expect(screen.getByText(/no overall grade/i)).toBeInTheDocument();
  });

  it('uses one chip-list grammar for both regimes in judgement detail', () => {
    render(<CompareOfsted schools={schools} data={data} />);
    // report-card area chip
    expect(screen.getByText('Attendance & behaviour')).toBeInTheDocument();
    expect(screen.getByText('Needs attention')).toBeInTheDocument();
    // graded school without published subgrades → honest dataset statement
    expect(
      screen.getAllByText(/We don't hold area-by-area detail/i).length,
    ).toBeGreaterThanOrEqual(1);
  });

  it('shows the mixed-regime comparability note only when regimes differ', () => {
    render(<CompareOfsted schools={schools} data={data} />);
    expect(screen.getByText(/aren't directly comparable/i)).toBeInTheDocument();
  });

  it('links every school to its Ofsted page', () => {
    render(<CompareOfsted schools={schools} data={data} />);
    const links = screen.getAllByRole('link', { name: /Ofsted page/i });
    expect(links).toHaveLength(3);
    expect(links[0]).toHaveAttribute('href', 'https://reports.ofsted.gov.uk/provider/21/1');
  });

  it('never renders Ofsted sentinel codes (9 = not applicable) as judgement chips', () => {
    const sentinelSchool = school(6, 'Sentinel School');
    const sentinelData: Record<string, ComparisonData> = {
      '6': {
        school_info: sentinelSchool,
        yearly_data: [],
        ofsted: ofsted({
          overall_effectiveness: 2,
          grade_source: 'graded',
          quality_of_education: 1,
          early_years_provision: 9,
          sixth_form_provision: 2,
        }),
      },
    };
    render(<CompareOfsted schools={[sentinelSchool]} data={sentinelData} />);
    // Real grades render…
    expect(screen.getByText('Quality of education')).toBeInTheDocument();
    // …the applicable sixth-form judgement renders (was previously dropped)…
    expect(screen.getByText('Sixth form provision')).toBeInTheDocument();
    // …and the not-applicable sentinel never appears, neither as area nor code.
    expect(screen.queryByText('Early years provision')).toBeNull();
    expect(screen.queryByText('9')).toBeNull();
  });

  it('dates a report card with the report-card inspection date, never the legacy date', () => {
    const cardSchool = school(4, 'Dated Card School');
    const cardData: Record<string, ComparisonData> = {
      '4': {
        school_info: cardSchool,
        yearly_data: [],
        ofsted: ofsted({
          inspection_date: '2021-10-07',
          rc_inspection_date: '2026-02-03',
          rc_safeguarding_met: true,
          report_card: { rc_achievement: { code: 1, label: 'Exceptional' } },
        }),
      },
    };
    render(<CompareOfsted schools={[cardSchool]} data={cardData} />);
    expect(screen.getByText(/3 Feb 2026/)).toBeInTheDocument();
    expect(screen.queryByText(/7 Oct 2021/)).toBeNull();
    expect(screen.queryByText('4+ years ago')).toBeNull();
  });

  it('shows an em dash when a report card has no rc_inspection_date yet', () => {
    const cardSchool = school(5, 'Undated Card School');
    const cardData: Record<string, ComparisonData> = {
      '5': {
        school_info: cardSchool,
        yearly_data: [],
        ofsted: ofsted({
          inspection_date: '2021-10-07',
          rc_inspection_date: null,
          rc_safeguarding_met: true,
          report_card: { rc_achievement: { code: 1, label: 'Exceptional' } },
        }),
      },
    };
    render(<CompareOfsted schools={[cardSchool]} data={cardData} />);
    expect(screen.getByText('—')).toBeInTheDocument();
    expect(screen.queryByText(/7 Oct 2021/)).toBeNull();
  });

  it('renders a per-measure mobile tag with the short school name', () => {
    render(<CompareOfsted schools={schools} data={data} />);
    // Each measure repeats the schools, so the short name ("Graded" from
    // "Graded School") appears once per measure (4) via the cell tag.
    expect(screen.getAllByText('Graded').length).toBe(4);
    expect(screen.getAllByText('Card').length).toBe(4);
  });
});
