/**
 * Explore trends — the full grouped metric catalogue (nothing from the old
 * compare page is lost; spec §4's tier 3) driving the year-by-year chart
 * with its England reference line, plus the year-by-year table. Progress
 * metrics carry CI-based bands for the years DfE published them.
 */

'use client';

import { useState } from 'react';
import dynamic from 'next/dynamic';

import { progressBand } from '@/lib/compareLogic';
import type { ComparisonData, MetricDefinition, NationalAverages, School } from '@/lib/types';
import { formatAcademicYear, formatMetricValue, metricKind } from '@/lib/utils';
import { track } from '@/lib/analytics';
import { Chip, Section, sectionStyles as s } from './sectionShared';
import styles from './TrendsExplorer.module.css';

const ComparisonChart = dynamic(
  () => import('../ComparisonChart').then((m) => m.ComparisonChart),
  { ssr: false },
);

const PRIMARY_OPTGROUPS: { label: string; category: string }[] = [
  { label: 'Expected Standard', category: 'expected' },
  { label: 'Higher Standard', category: 'higher' },
  { label: 'Progress Scores', category: 'progress' },
  { label: 'Average Scores', category: 'average' },
  { label: 'Gender Performance', category: 'gender' },
  { label: 'Equity (Disadvantaged)', category: 'equity' },
  { label: 'School Context', category: 'context' },
  { label: 'Absence', category: 'absence' },
  { label: '3-Year Trends', category: 'trends' },
];

const SECONDARY_OPTGROUPS: { label: string; category: string }[] = [
  { label: 'GCSE Performance', category: 'gcse' },
];

export const PRIMARY_CATEGORIES = PRIMARY_OPTGROUPS.map((g) => g.category);
export const SECONDARY_CATEGORIES = SECONDARY_OPTGROUPS.map((g) => g.category);

const PROGRESS_CI: Record<string, [string, string]> = {
  reading_progress: ['reading_progress_lower_ci', 'reading_progress_upper_ci'],
  writing_progress: ['writing_progress_lower_ci', 'writing_progress_upper_ci'],
  maths_progress: ['maths_progress_lower_ci', 'maths_progress_upper_ci'],
};

const BAND_LABEL = { above: 'Above average', average: 'Average', below: 'Below average' } as const;

export function TrendsExplorer({
  schools,
  data,
  metrics,
  initialMetric,
  isPrimaryPhase,
  nationalAverages,
}: {
  schools: School[];
  data: Record<string, ComparisonData>;
  metrics: MetricDefinition[];
  initialMetric: string;
  isPrimaryPhase: boolean;
  nationalAverages?: NationalAverages;
}) {
  const [metric, setMetric] = useState(initialMetric);

  const allowedCategories = isPrimaryPhase ? PRIMARY_CATEGORIES : SECONDARY_CATEGORIES;
  const optgroups = isPrimaryPhase ? PRIMARY_OPTGROUPS : SECONDARY_OPTGROUPS;
  const filteredMetrics = metrics.filter((m) => allowedCategories.includes(m.category));
  const metricDef = metrics.find((m) => m.key === metric);
  const metricLabel = metricDef?.label || metric;

  const nationalByYear: Record<number, number | null> = {};
  for (const entry of nationalAverages?.by_year ?? []) {
    const block = isPrimaryPhase ? entry.primary : entry.secondary;
    nationalByYear[entry.year] = block?.[metric] ?? null;
  }

  const years = [
    ...new Set(
      schools.flatMap(
        (school) => data[String(school.urn)]?.yearly_data.map((d) => Math.trunc(d.year)) ?? [],
      ),
    ),
  ].sort((a, b) => a - b);

  const handleMetricChange = (next: string) => {
    track('compare_metric_changed', { metric: next, phase: isPrimaryPhase ? 'primary' : 'secondary' });
    setMetric(next);
  };

  const ciKeys = PROGRESS_CI[metric];

  return (
    <Section
      title="Explore trends"
      how="The full year-by-year explorer for any measure, with the England average as a dashed reference line where official figures exist."
    >
      <details className={styles.explore} open>
        <summary>Year-by-year trends</summary>
        <div className={styles.inner}>
          <div className={styles.picker}>
            <label htmlFor="trends-metric-select">Measure:</label>
            <select
              id="trends-metric-select"
              value={metric}
              onChange={(e) => handleMetricChange(e.target.value)}
            >
              {optgroups.map(({ label, category }) => {
                const group = filteredMetrics.filter((m) => m.category === category);
                if (group.length === 0) return null;
                return (
                  <optgroup key={category} label={label}>
                    {group.map((m) => (
                      <option key={m.key} value={m.key}>
                        {m.label}
                      </option>
                    ))}
                  </optgroup>
                );
              })}
            </select>
            {metricDef?.description && <span className={styles.desc}>{metricDef.description}</span>}
          </div>

          {metric.includes('progress') && (
            <p className={styles.progressNote}>
              Progress scores measure pupils&apos; progress from KS1 to KS2. A score of 0 equals the
              national average. DfE stopped publishing KS2 progress after 2022/23 (no KS1 baseline);
              bands use DfE&apos;s confidence intervals, not the raw score alone.
            </p>
          )}

          <div className={styles.chartBox}>
            <ComparisonChart
              comparisonData={data}
              schools={schools}
              metric={metric}
              metricLabel={metricLabel}
              nationalByYear={nationalByYear}
            />
          </div>

          {years.length > 0 && (
            <div className={styles.tableWrapper}>
              <table className={styles.table}>
                <thead>
                  <tr>
                    <th>Year</th>
                    {schools.map((school) => (
                      <th key={school.urn}>{school.school_name}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {years.map((year) => (
                    <tr key={year}>
                      <td className={styles.yearCell}>{formatAcademicYear(year)}</td>
                      {schools.map((school) => {
                        const row = data[String(school.urn)]?.yearly_data.find(
                          (d) => Math.trunc(d.year) === year,
                        ) as (Record<string, unknown> & { year: number }) | undefined;
                        const value = row?.[metric];
                        if (typeof value !== 'number') return <td key={school.urn}>–</td>;
                        const band = ciKeys
                          ? progressBand(
                              value,
                              (row?.[ciKeys[0]] as number | null) ?? null,
                              (row?.[ciKeys[1]] as number | null) ?? null,
                            )
                          : null;
                        return (
                          <td key={school.urn}>
                            {formatMetricValue(value, metricKind(metric))}{' '}
                            {band && (
                              <Chip tone={band === 'above' ? 'good' : band === 'below' ? 'warn' : 'neutral'}>
                                {BAND_LABEL[band]}
                              </Chip>
                            )}
                          </td>
                        );
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </details>
    </Section>
  );
}
