/**
 * ComparisonView — the parent-first compare screen: a sticky school bar and
 * six sections (At a glance / Ofsted / Academics / Getting a place / Who
 * goes there / Explore trends), every number anchored against the England
 * average or the computed state-school benchmark with provenance-correct
 * labels. Layout and copy follow the reviewed mockups
 * (docs/superpowers/specs/mockups/).
 */

'use client';

import { useEffect, useRef, useState } from 'react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { useComparison } from '@/hooks/useComparison';

import { SchoolSearchModal } from './SchoolSearchModal';
import { EmptyState } from './EmptyState';
import { CompareAtAGlance } from './compare/CompareAtAGlance';
import { CompareOfsted } from './compare/CompareOfsted';
import { CompareAcademics } from './compare/CompareAcademics';
import { CompareAdmissions } from './compare/CompareAdmissions';
import { CompareCommunity } from './compare/CompareCommunity';
import { TrendsExplorer, PRIMARY_CATEGORIES, SECONDARY_CATEGORIES } from './compare/TrendsExplorer';
import type {
  Benchmarks,
  ComparisonData,
  MetricDefinition,
  NationalAverages,
  School,
} from '@/lib/types';
import { CHART_COLORS, schoolUrl } from '@/lib/utils';
import { fetchComparison } from '@/lib/api';
import { track } from '@/lib/analytics';
import styles from './ComparisonView.module.css';

interface ComparisonViewProps {
  initialData: Record<string, ComparisonData> | null;
  initialNationalAverages?: NationalAverages;
  initialBenchmarks?: Benchmarks;
  initialUrns: number[];
  metrics: MetricDefinition[];
  selectedMetric: string;
}

export function ComparisonView({
  initialData,
  initialNationalAverages,
  initialBenchmarks,
  initialUrns,
  metrics,
  selectedMetric: initialMetric,
}: ComparisonViewProps) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const { selectedSchools, removeSchool, replaceSchools, isInitialized } = useComparison();

  const [selectedMetric, setSelectedMetric] = useState(initialMetric);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [comparisonData, setComparisonData] = useState(initialData);
  const [nationalAverages, setNationalAverages] = useState<NationalAverages | undefined>(
    initialNationalAverages,
  );
  const [benchmarks, setBenchmarks] = useState<Benchmarks | undefined>(initialBenchmarks);
  const [shareConfirm, setShareConfirm] = useState(false);
  const [comparePhase, setComparePhase] = useState<'primary' | 'secondary'>('primary');
  // Tracks whether the user has explicitly clicked a phase tab.
  // While true, auto-phase detection is suppressed so manual selections aren't overridden.
  const phaseLockedByUser = useRef(false);

  // Seed context from the URL on mount. An explicit ?urns=… (e.g. a link a
  // parent shared with their partner) always wins over this visitor's stored
  // selection — otherwise the recipient silently sees their own old schools.
  // The replacement is then persisted like any other selection change.
  useEffect(() => {
    if (!isInitialized) return;
    if (initialUrns.length > 0 && initialData) {
      const urlSchools = initialUrns
        .map((urn) => initialData[String(urn)]?.school_info)
        .filter((info): info is NonNullable<typeof info> => Boolean(info));
      const sameSet =
        urlSchools.length === selectedSchools.length &&
        urlSchools.every((s) => selectedSchools.some((sel) => sel.urn === s.urn));
      if (urlSchools.length > 0 && !sameSet) {
        replaceSchools(urlSchools);
      }
    }
  }, [isInitialized]); // eslint-disable-line react-hooks/exhaustive-deps

  const urnKey = selectedSchools.map((s) => s.urn).join(',');

  // Sync the URL with the selection + metric. Pure navigation state — no
  // fetching here: metric changes are presentational (the data is already
  // client-side) and must not refire the comparison request.
  useEffect(() => {
    const params = new URLSearchParams(searchParams);

    if (urnKey) {
      params.set('urns', urnKey);
    } else {
      params.delete('urns');
    }

    params.set('metric', selectedMetric);

    const newUrl = `${pathname}?${params.toString()}`;
    router.replace(newUrl, { scroll: false });
  }, [urnKey, selectedMetric, pathname, searchParams, router]);

  // Fetch only when the school set changes. The very first run is skipped
  // when the SSR payload already covers the current set — no double-fetch
  // of data the server just rendered.
  const firstFetchRef = useRef(true);
  useEffect(() => {
    if (!urnKey) {
      setComparisonData(null);
      setNationalAverages(undefined);
      setBenchmarks(undefined);
      return;
    }

    if (firstFetchRef.current) {
      firstFetchRef.current = false;
      const ssrUrns = new Set(Object.keys(initialData ?? {}));
      const covered = urnKey.split(',').every((urn) => ssrUrns.has(urn));
      if (covered && ssrUrns.size > 0) return;
    }

    fetchComparison(urnKey, { cache: 'no-store' })
      .then((data) => {
        setComparisonData(data.comparison);
        setNationalAverages(data.national_averages);
        setBenchmarks(data.benchmarks);
      })
      .catch((err) => {
        // Keep whatever we already have (SSR data or a previous fetch) rather
        // than blanking the page — a transient refetch failure shouldn't
        // destroy a working comparison the user is looking at.
        console.error('Failed to fetch comparison:', err);
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [urnKey]);

  // Classify schools by phase using comparison data
  const classifySchool = (school: School): 'primary' | 'secondary' => {
    const info = comparisonData?.[school.urn]?.school_info;
    if (info?.attainment_8_score != null) return 'secondary';
    if (info?.rwm_expected_pct != null) return 'primary';
    // Fallback: check yearly data
    const yearlyData = comparisonData?.[school.urn]?.yearly_data;
    if (yearlyData?.some((d) => d.attainment_8_score != null)) return 'secondary';
    return 'primary';
  };

  const primarySchools = selectedSchools.filter((s) => classifySchool(s) === 'primary');
  const secondarySchools = selectedSchools.filter((s) => classifySchool(s) === 'secondary');

  // Auto-select tab with more schools and sync the metric to match the phase.
  useEffect(() => {
    if (!comparisonData || selectedSchools.length === 0) return;
    if (phaseLockedByUser.current) return;
    const newPhase = secondarySchools.length > primarySchools.length ? 'secondary' : 'primary';
    setComparePhase(newPhase);
    const phaseCategories = newPhase === 'secondary' ? SECONDARY_CATEGORIES : PRIMARY_CATEGORIES;
    const metricFitsPhase = metrics.some(
      (m) => m.key === selectedMetric && phaseCategories.includes(m.category),
    );
    if (!metricFitsPhase) {
      setSelectedMetric(newPhase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct');
    }
  }, [comparisonData]); // eslint-disable-line react-hooks/exhaustive-deps

  const handlePhaseChange = (phase: 'primary' | 'secondary') => {
    phaseLockedByUser.current = true;
    setComparePhase(phase);
    setSelectedMetric(phase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct');
  };

  // compare_viewed: fire once after the page has its first selection.
  const compareViewedRef = useRef(false);
  useEffect(() => {
    if (compareViewedRef.current) return;
    if (selectedSchools.length === 0) return;
    compareViewedRef.current = true;
    const primaryCount = selectedSchools.filter((s) =>
      s.phase?.toLowerCase().includes('primary'),
    ).length;
    const secondaryCount = selectedSchools.length - primaryCount;
    const phaseMix =
      primaryCount === 0 ? 'all_secondary' : secondaryCount === 0 ? 'all_primary' : 'mixed';
    track('compare_viewed', { school_count: selectedSchools.length, phase_mix: phaseMix });
  }, [selectedSchools]);

  const handleRemoveSchool = (urn: number) => {
    removeSchool(urn);
    track('compare_school_removed', { urn, from: 'compare' });
  };

  const handleShare = async () => {
    const url = window.location.href;
    const count = selectedSchools.length;
    const shareData = {
      title: 'School comparison · SchoolCompare',
      text:
        count > 0
          ? `Comparing ${count} school${count === 1 ? '' : 's'} on SchoolCompare`
          : 'SchoolCompare',
      url,
    };
    if (
      typeof navigator !== 'undefined' &&
      navigator.share &&
      (!navigator.canShare || navigator.canShare(shareData))
    ) {
      try {
        await navigator.share(shareData);
        track('compare_shared', { method: 'native', school_count: count });
        return;
      } catch (err) {
        if ((err as DOMException)?.name === 'AbortError') return;
      }
    }
    try {
      await navigator.clipboard.writeText(url);
      track('compare_shared', { method: 'clipboard', school_count: count });
      setShareConfirm(true);
      setTimeout(() => setShareConfirm(false), 2000);
    } catch {
      /* fallback: do nothing */
    }
  };

  const isPrimary = comparePhase === 'primary';
  const activeSchools = isPrimary ? primarySchools : secondarySchools;

  if (selectedSchools.length === 0) {
    return (
      <div className={styles.container}>
        <header className={styles.header}>
          <h1>Compare Schools</h1>
          <p className={styles.subtitle}>
            Add schools to your comparison basket to see them side by side — inspection results,
            academics, admissions and community.
          </p>
        </header>

        <EmptyState
          title="No schools selected"
          message="Add schools from the home page or search to start comparing."
          action={{
            label: '+ Add Schools to Compare',
            onClick: () => setIsModalOpen(true),
          }}
        />

        <SchoolSearchModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
      </div>
    );
  }

  // Build filtered comparison data for the active phase
  const activeComparisonData: Record<string, ComparisonData> = {};
  if (comparisonData) {
    activeSchools.forEach((s) => {
      if (comparisonData[s.urn]) {
        activeComparisonData[s.urn] = comparisonData[s.urn];
      }
    });
  }
  const hasData = Object.keys(activeComparisonData).length > 0;

  return (
    <div className={styles.container}>
      <header className={styles.header}>
        <div className={styles.headerContent}>
          <div>
            <h1>Compare Schools</h1>
            <p className={styles.subtitle}>
              {selectedSchools.length} school{selectedSchools.length !== 1 ? 's' : ''} side by side
              — each number anchored against the England average so you can tell at a glance
              what&apos;s typical and what stands out.
            </p>
          </div>
          <div className={styles.headerActions}>
            <button onClick={() => setIsModalOpen(true)} className="btn btn-primary">
              + Add School
            </button>
            <button onClick={handleShare} className="btn btn-tertiary" title="Copy comparison link">
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                width="16"
                height="16"
              >
                <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
                <polyline points="16 6 12 2 8 6" />
                <line x1="12" y1="2" x2="12" y2="15" />
              </svg>
              {shareConfirm ? 'Copied!' : 'Share'}
            </button>
          </div>
        </div>
      </header>

      {/* Phase Tabs */}
      {secondarySchools.length > 0 && primarySchools.length > 0 && (
        <div className={styles.phaseTabs}>
          <button
            className={`${styles.phaseTab} ${isPrimary ? styles.phaseTabActive : ''}`}
            onClick={() => handlePhaseChange('primary')}
          >
            Primary ({primarySchools.length})
          </button>
          <button
            className={`${styles.phaseTab} ${!isPrimary ? styles.phaseTabActive : ''}`}
            onClick={() => handlePhaseChange('secondary')}
          >
            Secondary ({secondarySchools.length})
          </button>
        </div>
      )}

      {activeSchools.length === 0 ? (
        <EmptyState
          title={`No ${comparePhase} schools in your comparison`}
          message={`Add ${comparePhase} schools from search results to compare them here.`}
          action={{
            label: '+ Add Schools',
            onClick: () => setIsModalOpen(true),
          }}
        />
      ) : (
        <>
          {/* Sticky school bar — column identity while scrolling */}
          <div className={styles.schoolBar} aria-label="Schools in this comparison">
            {activeSchools.map((school, index) => (
              <div
                key={school.urn}
                className={styles.schoolChip}
                style={{ borderTopColor: CHART_COLORS[index % CHART_COLORS.length] }}
              >
                <span
                  className={styles.chipDot}
                  style={{ background: CHART_COLORS[index % CHART_COLORS.length] }}
                  aria-hidden="true"
                />
                <span className={styles.chipText}>
                  <a className={styles.chipName} href={schoolUrl(school.urn, school.school_name)}>
                    {school.school_name}
                  </a>
                  <span className={styles.chipMeta}>
                    {[school.local_authority, school.school_type].filter(Boolean).join(' · ')}
                  </span>
                </span>
                <button
                  onClick={() => handleRemoveSchool(school.urn)}
                  className={styles.chipRemove}
                  aria-label={`Remove ${school.school_name}`}
                  title="Remove from comparison"
                >
                  ×
                </button>
              </div>
            ))}
          </div>

          {hasData && (
            <>
              <CompareAtAGlance
                schools={activeSchools}
                data={activeComparisonData}
                nationalAverages={nationalAverages}
                benchmarks={benchmarks}
              />
              <CompareOfsted schools={activeSchools} data={activeComparisonData} />
              <CompareAcademics
                schools={activeSchools}
                data={activeComparisonData}
                nationalAverages={nationalAverages}
                benchmarks={benchmarks}
              />
              <CompareAdmissions schools={activeSchools} data={activeComparisonData} />
              <CompareCommunity
                schools={activeSchools}
                data={activeComparisonData}
                benchmarks={benchmarks}
              />
              <TrendsExplorer
                schools={activeSchools}
                data={activeComparisonData}
                metrics={metrics}
                metric={selectedMetric}
                onMetricChange={setSelectedMetric}
                isPrimaryPhase={isPrimary}
                nationalAverages={nationalAverages}
              />

              <p className={styles.footnote}>
                Sources: DfE Compare School Performance (KS2/KS4 results), Ofsted inspection
                outcomes, DfE school admissions data, school census. England averages for test
                results are official DfE figures; other benchmarks are state-school averages
                computed from our dataset. Following DfE practice, figures based on 5 or fewer
                pupils are suppressed and shown as &quot;no data&quot;.
              </p>
            </>
          )}
        </>
      )}

      <SchoolSearchModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} />
    </div>
  );
}
