/**
 * ComparisonView Component
 * Client-side comparison interface with phase tabs, charts, and tables
 */

'use client';

import { useEffect, useState } from 'react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { useComparison } from '@/hooks/useComparison';
import { ComparisonChart } from './ComparisonChart';
import { SchoolSearchModal } from './SchoolSearchModal';
import { EmptyState } from './EmptyState';
import { LoadingSkeleton } from './LoadingSkeleton';
import type { ComparisonData, MetricDefinition, School } from '@/lib/types';
import { formatPercentage, formatProgress, formatAcademicYear, CHART_COLORS, schoolUrl } from '@/lib/utils';
import { fetchComparison } from '@/lib/api';
import styles from './ComparisonView.module.css';

const PRIMARY_CATEGORIES = ['expected', 'higher', 'progress', 'average', 'gender', 'equity', 'context', 'absence', 'trends'];
const SECONDARY_CATEGORIES = ['gcse'];

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' },
];

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

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

  const [selectedMetric, setSelectedMetric] = useState(initialMetric);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [comparisonData, setComparisonData] = useState(initialData);
  const [shareConfirm, setShareConfirm] = useState(false);
  const [comparePhase, setComparePhase] = useState<'primary' | 'secondary'>('primary');

  // Seed context from initialData when component mounts and localStorage is empty
  useEffect(() => {
    if (!isInitialized) return;
    if (selectedSchools.length === 0 && initialUrns.length > 0 && initialData) {
      initialUrns.forEach(urn => {
        const data = initialData[String(urn)];
        if (data?.school_info) {
          addSchool(data.school_info);
        }
      });
    }
  }, [isInitialized]); // eslint-disable-line react-hooks/exhaustive-deps

  // Sync URL with selected schools
  useEffect(() => {
    const urns = selectedSchools.map((s) => s.urn).join(',');
    const params = new URLSearchParams(searchParams);

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

    params.set('metric', selectedMetric);

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

    // Fetch comparison data
    if (selectedSchools.length > 0) {
      fetchComparison(urns, { cache: 'no-store' })
        .then((data) => {
          setComparisonData(data.comparison);
        })
        .catch((err) => {
          console.error('Failed to fetch comparison:', err);
          setComparisonData(null);
        });
    } else {
      setComparisonData(null);
    }
  }, [selectedSchools, selectedMetric, pathname, searchParams, router]);

  // 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: any) => 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 detected phase.
  // This fixes the case where the URL carries a primary metric (e.g. rwm_expected_pct)
  // but the shortlisted schools are secondary — the phase tab switches but the metric
  // needs to follow, otherwise all secondary cards show "–" for a primary-only field.
  useEffect(() => {
    if (!comparisonData || selectedSchools.length === 0) return;
    const newPhase = secondarySchools.length > primarySchools.length ? 'secondary' : 'primary';
    setComparePhase(newPhase);
    // Only reset the metric when it doesn't belong to the newly detected phase.
    // This preserves a correct metric that came from the URL (e.g. metric=attainment_8_score).
    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') => {
    setComparePhase(phase);
    const defaultMetric = phase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct';
    setSelectedMetric(defaultMetric);
  };

  const handleMetricChange = (metric: string) => {
    setSelectedMetric(metric);
  };

  const handleRemoveSchool = (urn: number) => {
    removeSchool(urn);
  };

  const handleShare = async () => {
    try {
      await navigator.clipboard.writeText(window.location.href);
      setShareConfirm(true);
      setTimeout(() => setShareConfirm(false), 2000);
    } catch { /* fallback: do nothing */ }
  };

  const isPrimary = comparePhase === 'primary';
  const allowedCategories = isPrimary ? PRIMARY_CATEGORIES : SECONDARY_CATEGORIES;
  const optgroups = isPrimary ? PRIMARY_OPTGROUPS : SECONDARY_OPTGROUPS;
  const filteredMetrics = metrics.filter(m => allowedCategories.includes(m.category));
  const activeSchools = isPrimary ? primarySchools : secondarySchools;

  // Get metric definition
  const currentMetricDef = metrics.find((m) => m.key === selectedMetric);
  const metricLabel = currentMetricDef?.label || selectedMetric;

  // No schools selected
  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 side-by-side performance data
          </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 active phase
  const activeComparisonData: Record<string, ComparisonData> = {};
  if (comparisonData) {
    activeSchools.forEach(s => {
      if (comparisonData[s.urn]) {
        activeComparisonData[s.urn] = comparisonData[s.urn];
      }
    });
  }

  // Get years for table
  const years =
    Object.keys(activeComparisonData).length > 0
      ? activeComparisonData[Object.keys(activeComparisonData)[0]].yearly_data.map((d) => d.year)
      : [];

  return (
    <div className={styles.container}>
      {/* Header */}
      <header className={styles.header}>
        <div className={styles.headerContent}>
          <div>
            <h1>Compare Schools</h1>
            <p className={styles.subtitle}>
              Comparing {selectedSchools.length} school{selectedSchools.length !== 1 ? 's' : ''}
            </p>
          </div>
          <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>
            <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 */}
      <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),
          }}
        />
      ) : (
        <>
          {/* Metric Selector */}
          <section className={styles.metricSelector}>
            <label htmlFor="metric-select" className={styles.metricLabel}>
              Select Metric:
            </label>
            <select
              id="metric-select"
              value={selectedMetric}
              onChange={(e) => handleMetricChange(e.target.value)}
              className={styles.metricSelect}
            >
              {optgroups.map(({ label, category }) => {
                const groupMetrics = filteredMetrics.filter(m => m.category === category);
                if (groupMetrics.length === 0) return null;
                return (
                  <optgroup key={category} label={label}>
                    {groupMetrics.map((metric) => (
                      <option key={metric.key} value={metric.key}>{metric.label}</option>
                    ))}
                  </optgroup>
                );
              })}
            </select>
            {currentMetricDef?.description && (
              <p className={styles.metricDescription}>{currentMetricDef.description}</p>
            )}
          </section>

          {/* Progress score explanation */}
          {selectedMetric.includes('progress') && (
            <p className={styles.progressNote}>
              Progress scores measure pupils&apos; progress from KS1 to KS2. A score of 0 equals the national average; positive scores are above average.
            </p>
          )}

          {/* School Cards */}
          <section className={styles.schoolsSection}>
            <div className={styles.schoolsGrid}>
              {activeSchools.map((school, index) => (
                <div
                  key={school.urn}
                  className={styles.schoolCard}
                  style={{ borderLeft: `3px solid ${CHART_COLORS[index % CHART_COLORS.length]}` }}
                >
                  <button
                    onClick={() => handleRemoveSchool(school.urn)}
                    className={styles.removeButton}
                    aria-label={`Remove ${school.school_name}`}
                    title="Remove from comparison"
                  >
                    ×
                  </button>
                  <h2 className={styles.schoolName}>
                    <a href={schoolUrl(school.urn, school.school_name)}>{school.school_name}</a>
                  </h2>
                  <div className={styles.schoolMeta}>
                    {school.local_authority && (
                      <span className={styles.metaItem}>{school.local_authority}</span>
                    )}
                    {school.school_type && (
                      <span className={styles.metaItem}>{school.school_type}</span>
                    )}
                  </div>

                  {/* Latest metric value */}
                  {activeComparisonData[school.urn] && (
                    <div className={styles.latestValue}>
                      <div className={styles.latestLabel}>{metricLabel}</div>
                      <div className={styles.latestNumber} style={{ color: CHART_COLORS[index % CHART_COLORS.length] }}>
                        <span
                          style={{
                            display: 'inline-block',
                            width: '10px',
                            height: '10px',
                            borderRadius: '50%',
                            background: CHART_COLORS[index % CHART_COLORS.length],
                            marginRight: '0.4rem',
                            verticalAlign: 'middle',
                          }}
                        />
                        {(() => {
                          const yearlyData = activeComparisonData[school.urn].yearly_data;
                          if (yearlyData.length === 0) return '-';

                          const latestData = yearlyData[yearlyData.length - 1];
                          const value = latestData[selectedMetric as keyof typeof latestData];

                          if (value === null || value === undefined) return '-';

                          if (selectedMetric.includes('progress')) {
                            return formatProgress(value as number);
                          } else if (selectedMetric.includes('pct') || selectedMetric.includes('rate')) {
                            return formatPercentage(value as number);
                          } else {
                            return typeof value === 'number' ? value.toFixed(1) : String(value);
                          }
                        })()}
                      </div>
                    </div>
                  )}
                </div>
              ))}
            </div>
          </section>

          {/* Comparison Chart */}
          {Object.keys(activeComparisonData).length > 0 ? (
            <section className={styles.chartSection}>
              <h2 className={styles.sectionTitle}>Performance Over Time</h2>
              <div className={styles.chartContainer}>
                <ComparisonChart
                  comparisonData={activeComparisonData}
                  metric={selectedMetric}
                  metricLabel={metricLabel}
                />
              </div>
            </section>
          ) : activeSchools.length > 0 ? (
            <section className={styles.chartSection}>
              <LoadingSkeleton type="list" />
            </section>
          ) : null}

          {/* Comparison Table */}
          {Object.keys(activeComparisonData).length > 0 && years.length > 0 && (
            <section className={styles.tableSection}>
              <h2 className={styles.sectionTitle}>Detailed Comparison</h2>
              <div className={styles.tableWrapper}>
                <table className={styles.comparisonTable}>
                  <thead>
                    <tr>
                      <th>Year</th>
                      {activeSchools.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>
                        {activeSchools.map((school) => {
                          const schoolData = activeComparisonData[school.urn];
                          if (!schoolData) return <td key={school.urn}>-</td>;

                          const yearData = schoolData.yearly_data.find((d) => d.year === year);
                          if (!yearData) return <td key={school.urn}>-</td>;

                          const value = yearData[selectedMetric as keyof typeof yearData];

                          if (value === null || value === undefined) {
                            return <td key={school.urn}>-</td>;
                          }

                          let displayValue: string;
                          if (selectedMetric.includes('progress')) {
                            displayValue = formatProgress(value as number);
                          } else if (selectedMetric.includes('pct') || selectedMetric.includes('rate')) {
                            displayValue = formatPercentage(value as number);
                          } else {
                            displayValue = typeof value === 'number' ? value.toFixed(1) : String(value);
                          }

                          return <td key={school.urn}>{displayValue}</td>;
                        })}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </section>
          )}
        </>
      )}

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