/**
 * RankingsView Component
 * Client-side rankings interface with phase tabs and filters
 */

'use client';

import { useRouter, usePathname, useSearchParams } from 'next/navigation';
import { useComparison } from '@/hooks/useComparison';
import type { RankingEntry, Filters, MetricDefinition } from '@/lib/types';
import { formatPercentage, formatProgress, formatAcademicYear, schoolUrl } from '@/lib/utils';
import { track } from '@/lib/analytics';
import { EmptyState } from './EmptyState';
import styles from './RankingsView.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 RankingsViewProps {
  rankings: RankingEntry[];
  filters: Filters;
  metrics: MetricDefinition[];
  selectedMetric: string;
  selectedArea?: string;
  selectedYear?: number;
  selectedPhase?: string;
}

export function RankingsView({
  rankings,
  filters,
  metrics,
  selectedMetric,
  selectedArea,
  selectedYear,
  selectedPhase = 'primary',
}: RankingsViewProps) {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const { addSchool, isSelected } = useComparison();

  const isPrimary = selectedPhase === 'primary';
  const allowedCategories = isPrimary ? PRIMARY_CATEGORIES : SECONDARY_CATEGORIES;
  const optgroups = isPrimary ? PRIMARY_OPTGROUPS : SECONDARY_OPTGROUPS;

  const updateFilters = (updates: Record<string, string | undefined>) => {
    const params = new URLSearchParams(searchParams);

    Object.entries(updates).forEach(([key, value]) => {
      if (value) {
        params.set(key, value);
      } else {
        params.delete(key);
      }
    });

    router.push(`${pathname}?${params.toString()}`);
  };

  const handlePhaseChange = (phase: string) => {
    const defaultMetric = phase === 'secondary' ? 'attainment_8_score' : 'rwm_expected_pct';
    updateFilters({ phase, metric: defaultMetric });
  };

  const handleMetricChange = (metric: string) => {
    track('metric_compared_in_rankings', { metric, phase: selectedPhase });
    updateFilters({ metric });
  };

  const handleAreaChange = (area: string) => {
    updateFilters({ local_authority: area || undefined });
  };

  const handleYearChange = (year: string) => {
    updateFilters({ year: year || undefined });
  };

  const handleAddToCompare = (ranking: RankingEntry) => {
    addSchool({
      ...ranking,
      address: null,
      postcode: null,
      latitude: null,
      longitude: null,
    } as any);
    track('compare_school_added', { urn: ranking.urn, from: 'rankings' });
  };

  // Get metric definition
  const currentMetricDef = metrics.find((m) => m.key === selectedMetric);
  const metricLabel = currentMetricDef?.label || selectedMetric;
  const isProgressScore = selectedMetric.includes('progress');
  const isPercentage = selectedMetric.includes('pct') || selectedMetric.includes('rate');

  // Filter metrics to only show relevant categories
  const filteredMetrics = metrics.filter(m => allowedCategories.includes(m.category));

  return (
    <div className={styles.container}>
      {/* Header */}
      <header className={styles.header}>
        <h1>School Rankings</h1>
        <p className={styles.subtitle}>
          Top-performing schools by {metricLabel.toLowerCase()}
          {!selectedArea && rankings.length > 0 && <span className={styles.limitNote}> — showing top {rankings.length}</span>}
        </p>
      </header>

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

      {currentMetricDef?.description && (
        <p className={styles.metricDescription}>{currentMetricDef.description}</p>
      )}
      {isProgressScore && (
        <p className={styles.progressHint}>Progress scores: 0 = national average. Positive = above average.</p>
      )}

      {/* Filters */}
      <section className={styles.filters}>
        <div className={styles.filterGroup}>
          <label htmlFor="metric-select" className={styles.filterLabel}>
            Metric:
          </label>
          <select
            id="metric-select"
            value={selectedMetric}
            onChange={(e) => handleMetricChange(e.target.value)}
            className={styles.filterSelect}
          >
            {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>
        </div>

        <div className={styles.filterGroup}>
          <label htmlFor="area-select" className={styles.filterLabel}>
            Area:
          </label>
          <select
            id="area-select"
            value={selectedArea || ''}
            onChange={(e) => handleAreaChange(e.target.value)}
            className={styles.filterSelect}
          >
            <option value="">All Areas</option>
            {filters.local_authorities.map((area) => (
              <option key={area} value={area}>
                {area}
              </option>
            ))}
          </select>
        </div>

        <div className={styles.filterGroup}>
          <label htmlFor="year-select" className={styles.filterLabel}>
            Year:
          </label>
          <select
            id="year-select"
            value={selectedYear?.toString() || ''}
            onChange={(e) => handleYearChange(e.target.value)}
            className={styles.filterSelect}
          >
            <option value="">
              {filters.years.length > 0 ? `${formatAcademicYear(Math.max(...filters.years))} (Latest)` : 'Latest'}
            </option>
            {filters.years.map((year) => (
              <option key={year} value={year}>
                {formatAcademicYear(year)}
              </option>
            ))}
          </select>
        </div>
      </section>

      {/* Rankings Table */}
      <section className={styles.rankingsSection}>
        {rankings.length === 0 ? (
          <EmptyState
            title="No rankings found"
            message="Try selecting a different metric, area, or year."
            action={{
              label: 'Clear filters',
              onClick: () => router.push(`${pathname}?phase=${selectedPhase}`),
            }}
          />
        ) : (
          <div className={styles.tableWrapper}>
            <table className={styles.rankingsTable}>
              <thead>
                <tr>
                  <th className={styles.rankHeader}>Rank</th>
                  <th className={styles.schoolHeader}>School</th>
                  <th className={styles.areaHeader}>Area</th>
                  <th className={styles.typeHeader}>Type</th>
                  <th className={styles.valueHeader}>
                    {/* Inner block caps the column's measured width so long
                        labels wrap instead of widening the table off-screen. */}
                    <span className={styles.valueHeaderText}>{metricLabel}</span>
                  </th>
                  <th className={styles.actionHeader}>Action</th>
                </tr>
              </thead>
              <tbody>
                {rankings.map((ranking, index) => {
                  const rank = index + 1;
                  const isTopThree = rank <= 3;
                  const alreadyInComparison = isSelected(ranking.urn);

                  // Format the value
                  let displayValue: string;
                  if (ranking.value === null || ranking.value === undefined) {
                    displayValue = '-';
                  } else if (isProgressScore) {
                    displayValue = formatProgress(ranking.value);
                  } else if (isPercentage) {
                    displayValue = formatPercentage(ranking.value);
                  } else {
                    displayValue = ranking.value.toFixed(1);
                  }

                  return (
                    <tr
                      key={ranking.urn}
                      className={isTopThree ? styles[`rank${rank}`] : ''}
                    >
                      <td className={styles.rankCell}>
                        {isTopThree ? (
                          <span className={`${styles.rankBadge} ${styles[`rankBadge${rank}`]}`}>
                            {rank}
                          </span>
                        ) : (
                          <span className={styles.rankNumber}>{rank}</span>
                        )}
                      </td>
                      <td className={styles.schoolCell}>
                        <a href={schoolUrl(ranking.urn, ranking.school_name)} className={styles.schoolLink}>
                          {ranking.school_name}
                        </a>
                        {/* On phones the Area column is hidden; the LA moves here
                            so the metric value fits on screen without swiping. */}
                        {ranking.local_authority && (
                          <span className={styles.schoolCellArea}>{ranking.local_authority}</span>
                        )}
                      </td>
                      <td className={styles.areaCell}>{ranking.local_authority || '-'}</td>
                      <td className={styles.typeCell}>{ranking.school_type || '-'}</td>
                      <td className={styles.valueCell}>
                        <strong>{displayValue}</strong>
                      </td>
                      <td className={styles.actionCell}>
                        <a href={schoolUrl(ranking.urn, ranking.school_name)} className="btn btn-tertiary btn-sm">View</a>
                        <button
                          onClick={() => handleAddToCompare(ranking)}
                          disabled={alreadyInComparison}
                          className={alreadyInComparison ? 'btn btn-active btn-sm' : 'btn btn-secondary btn-sm'}
                        >
                          {alreadyInComparison ? '✓ Comparing' : '+ Compare'}
                        </button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </section>
    </div>
  );
}
