import React, { useState, useMemo, useCallback, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Line, Bar } from 'react-chartjs-2';
import { EmptyState, FilterControls, MultiSelect } from './shared';
import { ExportableChart } from './ChartExport';
import { chartColors, createBaseOptions } from '../config/chartConfig';
import { useLanguage } from '../contexts/LanguageContext';
import {
  filterDataByDateRange,
  calculateMetrics,
  formatCompact,
  formatCompactCurrency,
  umrahData,
  getUniqueChannels,
  getUniqueMuseums,
  getUniqueDistricts,
  getMuseumsForDistrict,
  getLatestYear
} from '../services/dataService';
import type { MuseumRecord, ComparisonProps, DateRangeFilters, Season } from '../types';

interface PresetDateRange {
  start: string;
  end: string;
}

interface PresetDates {
  [key: string]: PresetDateRange;
}

interface MetricCardProps {
  title: string;
  prev: number | null;
  curr: number | null;
  change: number | null;
  isCurrency?: boolean;
  isPercent?: boolean;
  pendingMessage?: string;
  prevYear: string;
  currYear: string;
}

// Generate preset dates for a given year
const generatePresetDates = (year: number): PresetDates => ({
  'jan': { start: `${year}-01-01`, end: `${year}-01-31` },
  'feb': { start: `${year}-02-01`, end: `${year}-02-28` },
  'mar': { start: `${year}-03-01`, end: `${year}-03-31` },
  'apr': { start: `${year}-04-01`, end: `${year}-04-30` },
  'may': { start: `${year}-05-01`, end: `${year}-05-31` },
  'jun': { start: `${year}-06-01`, end: `${year}-06-30` },
  'jul': { start: `${year}-07-01`, end: `${year}-07-31` },
  'aug': { start: `${year}-08-01`, end: `${year}-08-31` },
  'sep': { start: `${year}-09-01`, end: `${year}-09-30` },
  'oct': { start: `${year}-10-01`, end: `${year}-10-31` },
  'nov': { start: `${year}-11-01`, end: `${year}-11-30` },
  'dec': { start: `${year}-12-01`, end: `${year}-12-31` },
  'q1': { start: `${year}-01-01`, end: `${year}-03-31` },
  'q2': { start: `${year}-04-01`, end: `${year}-06-30` },
  'q3': { start: `${year}-07-01`, end: `${year}-09-30` },
  'q4': { start: `${year}-10-01`, end: `${year}-12-31` },
  'h1': { start: `${year}-01-01`, end: `${year}-06-30` },
  'h2': { start: `${year}-07-01`, end: `${year}-12-31` },
  'full': { start: `${year}-01-01`, end: `${year}-12-31` }
});

function Comparison({ data, seasons, showDataLabels, setShowDataLabels, includeVAT, setIncludeVAT, allowedMuseums, allowedChannels }: ComparisonProps) {
  const { t } = useLanguage();
  const [searchParams, setSearchParams] = useSearchParams();

  // Permission base filter — applied before any user-facing filter
  const permissionFilteredData = useMemo(() => {
    if (allowedMuseums === null || allowedChannels === null) return [];
    let d = data;
    if (allowedMuseums.length > 0) d = d.filter(r => allowedMuseums.includes(r.museum_name));
    if (allowedChannels.length > 0) d = d.filter(r => allowedChannels.includes(r.channel));
    return d;
  }, [data, allowedMuseums, allowedChannels]);

  // Get available years from data
  const latestYear = useMemo(() => parseInt(getLatestYear(permissionFilteredData)), [permissionFilteredData]);
  const availableYears = useMemo((): number[] => {
    const yearsSet = new Set<number>();
    permissionFilteredData.forEach((r: MuseumRecord) => {
      const d = r.date || (r as any).Date;
      if (d) yearsSet.add(new Date(d).getFullYear());
    });
    const years = Array.from(yearsSet).sort((a, b) => b - a);
    return years.length ? years : [new Date().getFullYear()];
  }, [data]);

  // Initialize state from URL or defaults
  const [selectedYear, setSelectedYearState] = useState<number>(() => {
    const urlYear = searchParams.get('year');
    return urlYear ? parseInt(urlYear) : latestYear;
  });
  const presetDates = useMemo(() => generatePresetDates(selectedYear), [selectedYear]);

  const [preset, setPresetState] = useState(() => searchParams.get('preset') || 'jan');
  const [startDate, setStartDateState] = useState(() => {
    const urlPreset = searchParams.get('preset');
    const yearParam = searchParams.get('year');
    const year = yearParam ? parseInt(yearParam) : latestYear;
    const dates = generatePresetDates(year);
    if (urlPreset && urlPreset !== 'custom' && dates[urlPreset]) {
      return dates[urlPreset].start;
    }
    // Season presets store from/to in URL
    const fromParam = searchParams.get('from');
    if (fromParam) return fromParam;
    return `${year}-01-01`;
  });
  const [endDate, setEndDateState] = useState(() => {
    const urlPreset = searchParams.get('preset');
    const yearParam = searchParams.get('year');
    const year = yearParam ? parseInt(yearParam) : latestYear;
    const dates = generatePresetDates(year);
    if (urlPreset && urlPreset !== 'custom' && dates[urlPreset]) {
      return dates[urlPreset].end;
    }
    // Season presets store from/to in URL
    const toParam = searchParams.get('to');
    if (toParam) return toParam;
    return `${year}-01-31`;
  });
  const [filters, setFiltersState] = useState(() => ({
    district: searchParams.get('district') || 'all',
    channel: searchParams.get('channel')?.split(',').filter(Boolean) || [],
    museum: searchParams.get('museum')?.split(',').filter(Boolean) || []
  }));
  
  const [chartMetric, setChartMetric] = useState('revenue');
  const [chartGranularity, setChartGranularity] = useState('week');
  const [activeChart, setActiveChart] = useState(0);
  const [activeCard, setActiveCard] = useState(0);

  // Update URL with current state
  const updateUrl = useCallback((newPreset: string, newFrom: string | null, newTo: string | null, newFilters: DateRangeFilters | null, newYear: number) => {
    const params = new URLSearchParams();
    if (newPreset && newPreset !== 'jan') params.set('preset', newPreset);
    if (newYear && newYear !== latestYear) params.set('year', newYear.toString());
    if (newPreset === 'custom' || newPreset.startsWith('season-')) {
      if (newFrom) params.set('from', newFrom);
      if (newTo) params.set('to', newTo);
    }
    if (newFilters?.district && newFilters.district !== 'all') params.set('district', newFilters.district);
    if (newFilters?.channel && newFilters.channel.length > 0) params.set('channel', newFilters.channel.join(','));
    if (newFilters?.museum && newFilters.museum.length > 0) params.set('museum', newFilters.museum.join(','));
    setSearchParams(params, { replace: true });
  }, [setSearchParams, latestYear]);

  const setSelectedYear = (year: number) => {
    setSelectedYearState(year);
    const newDates = generatePresetDates(year);
    if (preset !== 'custom' && !preset.startsWith('season-') && newDates[preset]) {
      setStartDateState(newDates[preset].start);
      setEndDateState(newDates[preset].end);
    }
    updateUrl(preset, null, null, filters, year);
  };

  const setPreset = (value: string) => {
    setPresetState(value);
    if (value.startsWith('season-')) {
      const seasonId = parseInt(value.replace('season-', ''));
      const season = seasons.find(s => s.Id === seasonId);
      if (season) {
        setStartDateState(season.StartDate);
        setEndDateState(season.EndDate);
        updateUrl(value, season.StartDate, season.EndDate, filters, selectedYear);
      }
    } else if (value !== 'custom' && presetDates[value]) {
      setStartDateState(presetDates[value].start);
      setEndDateState(presetDates[value].end);
      updateUrl(value, null, null, filters, selectedYear);
    }
  };

  const setStartDate = (value: string) => {
    setStartDateState(value);
    setPresetState('custom');
    updateUrl('custom', value, endDate, filters, selectedYear);
  };

  const setEndDate = (value: string) => {
    setEndDateState(value);
    setPresetState('custom');
    updateUrl('custom', startDate, value, filters, selectedYear);
  };

  const setFilters = (newFilters: DateRangeFilters | ((prev: DateRangeFilters) => DateRangeFilters)) => {
    const updated = typeof newFilters === 'function' ? newFilters(filters) : newFilters;
    setFiltersState(updated);
    updateUrl(preset, startDate, endDate, updated, selectedYear);
  };
  
  const charts = [
    { id: 'timeseries', label: t('comparison.trend') },
    { id: 'museum', label: t('comparison.byMuseum') }
  ];

  // Touch swipe handlers
  const touchStartChart = useRef<number | null>(null);
  const touchStartCard = useRef<number | null>(null);
  
  const handleChartTouchStart = (e: React.TouchEvent) => {
    touchStartChart.current = e.touches[0].clientX;
  };
  const handleChartTouchEnd = (e: React.TouchEvent) => {
    if (!touchStartChart.current) return;
    const diff = touchStartChart.current - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 50) {
      if (diff > 0 && activeChart < charts.length - 1) {
        setActiveChart(activeChart + 1);
      } else if (diff < 0 && activeChart > 0) {
        setActiveChart(activeChart - 1);
      }
    }
    touchStartChart.current = null;
  };

  const granularityOptions = [
    { value: 'day', label: t('time.daily') },
    { value: 'week', label: t('time.weekly') },
    { value: 'month', label: t('time.monthly') }
  ];

  const revenueField = includeVAT ? 'revenue_gross' : 'revenue_net';
  
  const metricOptions = [
    { value: 'revenue', label: t('metrics.revenue'), field: revenueField, format: 'currency' },
    { value: 'visitors', label: t('metrics.visitors'), field: 'visits', format: 'number' },
    { value: 'tickets', label: t('metrics.tickets'), field: 'tickets', format: 'number' },
    { value: 'avgRevenue', label: t('metrics.avgRevenue'), field: null, format: 'currency' }
  ];

  const getMetricValue = useCallback((rows: MuseumRecord[], metric: string) => {
    if (metric === 'avgRevenue') {
      const revenue = rows.reduce((s: number, r: MuseumRecord) => s + parseFloat(String((r as any)[revenueField] || 0)), 0);
      const visitors = rows.reduce((s: number, r: MuseumRecord) => s + parseInt(String(r.visits || 0)), 0);
      return visitors > 0 ? revenue / visitors : 0;
    }
    const fieldMap: Record<string, string> = { revenue: revenueField, visitors: 'visits', tickets: 'tickets' };
    const field = fieldMap[metric];
    return rows.reduce((s: number, r: MuseumRecord) => s + parseFloat(String((r as any)[field] || 0)), 0);
  }, [revenueField]);

  // Dynamic lists from data
  const channels = useMemo(() => getUniqueChannels(permissionFilteredData), [permissionFilteredData]);
  const districts = useMemo(() => getUniqueDistricts(permissionFilteredData), [permissionFilteredData]);
  const availableMuseums = useMemo(() => getMuseumsForDistrict(permissionFilteredData, filters.district), [permissionFilteredData, filters.district]);

  // Year-over-year comparison: same dates, previous year
  // For season presets, try to find the same season name from the previous hijri year
  const ranges = useMemo(() => {
    const curr = { start: startDate, end: endDate };
    let prev = {
      start: startDate.replace(/^(\d{4})/, (_: string, y: string) => String(parseInt(y) - 1)),
      end: endDate.replace(/^(\d{4})/, (_: string, y: string) => String(parseInt(y) - 1))
    };

    if (preset.startsWith('season-')) {
      const seasonId = parseInt(preset.replace('season-', ''));
      const currentSeason = seasons.find(s => s.Id === seasonId);
      if (currentSeason) {
        const prevSeason = seasons.find(
          s => s.Name === currentSeason.Name && s.HijriYear === currentSeason.HijriYear - 1
        );
        if (prevSeason) {
          prev = { start: prevSeason.StartDate, end: prevSeason.EndDate };
        }
      }
    }

    return { curr, prev };
  }, [startDate, endDate, preset, seasons]);

  const prevData = useMemo(() =>
    filterDataByDateRange(permissionFilteredData, ranges.prev.start, ranges.prev.end, filters),
    [permissionFilteredData, ranges.prev, filters]
  );

  const currData = useMemo(() =>
    filterDataByDateRange(permissionFilteredData, ranges.curr.start, ranges.curr.end, filters),
    [permissionFilteredData, ranges.curr, filters]
  );

  const prevMetrics = useMemo(() => calculateMetrics(prevData, includeVAT), [prevData, includeVAT]);
  const currMetrics = useMemo(() => calculateMetrics(currData, includeVAT), [currData, includeVAT]);
  
  const hasData = prevData.length > 0 || currData.length > 0;
  const resetFilters = () => setFilters({ district: 'all', channel: [], museum: [] });

  const calcChange = (prev: number, curr: number) => prev === 0 ? (curr > 0 ? Infinity : 0) : ((curr - prev) / prev * 100);

  // Get quarter from date range (returns null if not a clean quarter)
  const getQuarterFromRange = (start: string, end: string) => {
    const quarterRanges: Record<number, { start: string; end: string }> = {
      1: { start: '-01-01', end: '-03-31' },
      2: { start: '-04-01', end: '-06-30' },
      3: { start: '-07-01', end: '-09-30' },
      4: { start: '-10-01', end: '-12-31' }
    };
    for (let q = 1; q <= 4; q++) {
      if (start.endsWith(quarterRanges[q].start) && end.endsWith(quarterRanges[q].end)) {
        return q;
      }
    }
    return null;
  };

  // Estimate pilgrims for any date range by prorating quarterly data
  const estimatePilgrims = useCallback((start: string, end: string): number | null => {
    const startDate = new Date(start);
    const endDate = new Date(end);
    let total = 0;
    let hasData = false;
    
    // Iterate through each quarter that overlaps with the range
    const startYear = startDate.getFullYear();
    const endYear = endDate.getFullYear();
    
    for (let year = startYear; year <= endYear; year++) {
      for (let q = 1; q <= 4; q++) {
        const qStart = new Date(year, (q - 1) * 3, 1);
        const qEnd = new Date(year, q * 3, 0); // last day of quarter
        
        // Check overlap
        if (qEnd < startDate || qStart > endDate) continue;
        
        const pilgrims = umrahData[year]?.[q];
        if (!pilgrims) continue;
        
        // Calculate overlap fraction
        const overlapStart = new Date(Math.max(qStart.getTime(), startDate.getTime()));
        const overlapEnd = new Date(Math.min(qEnd.getTime(), endDate.getTime()));
        const overlapDays = (overlapEnd.getTime() - overlapStart.getTime()) / (1000 * 60 * 60 * 24) + 1;
        const quarterDays = (qEnd.getTime() - qStart.getTime()) / (1000 * 60 * 60 * 24) + 1;
        
        total += pilgrims * (overlapDays / quarterDays);
        hasData = true;
      }
    }
    
    return hasData ? Math.round(total) : null;
  }, []);

  // Calculate capture rate and pilgrim data for any date range
  const quarterData = useMemo(() => {
    const prevPilgrims = estimatePilgrims(ranges.prev.start, ranges.prev.end);
    const currPilgrims = estimatePilgrims(ranges.curr.start, ranges.curr.end);
    
    if (!prevPilgrims && !currPilgrims) return null;
    
    const prevRate = prevPilgrims ? (prevMetrics.visitors / prevPilgrims * 100) : null;
    const currRate = currPilgrims ? (currMetrics.visitors / currPilgrims * 100) : null;
    
    return { 
      pilgrims: { prev: prevPilgrims, curr: currPilgrims },
      captureRate: { prev: prevRate, curr: currRate }
    };
  }, [ranges, prevMetrics.visitors, currMetrics.visitors, estimatePilgrims]);

  const captureRates = quarterData?.captureRate || null;
  const pilgrimCounts = quarterData?.pilgrims || null;

  // Build cards array dynamically
  interface CardData {
    title: string;
    prev: number | null;
    curr: number | null;
    change: number | null;
    isCurrency?: boolean;
    isPercent?: boolean;
    pendingMessage?: string;
  }

  const metricCards = useMemo((): CardData[] => {
    const revenueChange = calcChange(prevMetrics.revenue, currMetrics.revenue);
    const visitorsChange = calcChange(prevMetrics.visitors, currMetrics.visitors);
    const ticketsChange = calcChange(prevMetrics.tickets, currMetrics.tickets);
    const avgRevChange = calcChange(prevMetrics.avgRevPerVisitor, currMetrics.avgRevPerVisitor);
    const pilgrimsChange = pilgrimCounts ? calcChange(pilgrimCounts.prev || 0, pilgrimCounts.curr || 0) : null;
    const captureRateChange = captureRates ? calcChange(captureRates.prev || 0, captureRates.curr || 0) : null;

    const cards: CardData[] = [
      { title: t('metrics.revenue'), prev: prevMetrics.revenue, curr: currMetrics.revenue, change: revenueChange, isCurrency: true },
      { title: t('metrics.visitors'), prev: prevMetrics.visitors, curr: currMetrics.visitors, change: visitorsChange },
      { title: t('metrics.tickets'), prev: prevMetrics.tickets, curr: currMetrics.tickets, change: ticketsChange },
      { title: t('metrics.avgRevenue'), prev: prevMetrics.avgRevPerVisitor, curr: currMetrics.avgRevPerVisitor, change: avgRevChange, isCurrency: true }
    ];
    if (pilgrimCounts) {
      cards.push({ title: t('metrics.pilgrims'), prev: pilgrimCounts.prev, curr: pilgrimCounts.curr, change: pilgrimsChange, pendingMessage: t('comparison.pendingData') });
    }
    if (captureRates) {
      cards.push({ title: t('metrics.captureRate'), prev: captureRates.prev, curr: captureRates.curr, change: captureRateChange, isPercent: true, pendingMessage: t('comparison.pendingData') });
    }
    return cards;
  }, [prevMetrics, currMetrics, pilgrimCounts, captureRates, t]);

  const handleCardTouchStart = (e: React.TouchEvent) => {
    touchStartCard.current = e.touches[0].clientX;
  };
  const handleCardTouchEnd = (e: React.TouchEvent) => {
    if (!touchStartCard.current) return;
    const diff = touchStartCard.current - e.changedTouches[0].clientX;
    if (Math.abs(diff) > 50) {
      if (diff > 0 && activeCard < metricCards.length - 1) {
        setActiveCard(activeCard + 1);
      } else if (diff < 0 && activeCard > 0) {
        setActiveCard(activeCard - 1);
      }
    }
    touchStartCard.current = null;
  };

  const formatDate = (dateStr: string) => {
    if (!dateStr) return '';
    const [year, month, day] = dateStr.split('-').map(Number);
    const d = new Date(year, month - 1, day);
    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
  };

  // Generate period label - shows year if same year, or "MMM YY–MMM YY" if spans years
  const getPeriodLabel = useCallback((startDate: string, endDate: string) => {
    if (!startDate || !endDate) return '';
    const startYear = startDate.substring(0, 4);
    const endYear = endDate.substring(0, 4);
    
    if (startYear === endYear) {
      return startYear;
    }
    
    // Spans multiple years - show abbreviated range
    const [sy, sm] = startDate.split('-').map(Number);
    const [ey, em] = endDate.split('-').map(Number);
    const startMonth = new Date(sy, sm - 1, 1).toLocaleDateString('en-US', { month: 'short' });
    const endMonth = new Date(ey, em - 1, 1).toLocaleDateString('en-US', { month: 'short' });
    return `${startMonth} ${String(sy).slice(-2)}–${endMonth} ${String(ey).slice(-2)}`;
  }, []);

  // Time series chart (daily or weekly)
  const timeSeriesChart = useMemo(() => {
    const groupByPeriod = (periodData: MuseumRecord[], periodStart: string, metric: string, granularity: string) => {
      const start = new Date(periodStart);
      const groupedRows: Record<number, MuseumRecord[]> = {};

      periodData.forEach((row: MuseumRecord) => {
        if (!row.date) return;
        const rowDate = new Date(row.date);
        const daysDiff = Math.floor((rowDate.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
        
        let key;
        if (granularity === 'month') {
          // Group by month number (relative to start)
          const monthsDiff = (rowDate.getFullYear() - start.getFullYear()) * 12 + (rowDate.getMonth() - start.getMonth());
          key = monthsDiff + 1;
        } else if (granularity === 'week') {
          key = Math.floor(daysDiff / 7) + 1;
        } else {
          key = daysDiff + 1; // day number from start
        }
        
        if (!groupedRows[key]) groupedRows[key] = [];
        groupedRows[key].push(row);
      });
      
      const result: Record<number, number> = {};
      Object.keys(groupedRows).forEach(key => {
        result[Number(key)] = getMetricValue(groupedRows[Number(key)], metric);
      });
      return result;
    };

    const prevGrouped = groupByPeriod(prevData, ranges.prev.start, chartMetric, chartGranularity);
    const currGrouped = groupByPeriod(currData, ranges.curr.start, chartMetric, chartGranularity);
    const maxKey = Math.max(...Object.keys(prevGrouped).map(Number), ...Object.keys(currGrouped).map(Number), 1);
    
    const labels = Array.from({ length: maxKey }, (_, i) => {
      if (chartGranularity === 'month') {
        const startDate = new Date(ranges.curr.start);
        const monthNum = ((startDate.getMonth() + i) % 12) + 1;
        return String(monthNum);
      }
      if (chartGranularity === 'week') return `W${i + 1}`;
      return `D${i + 1}`;
    });

    const prevLabel = getPeriodLabel(ranges.prev.start, ranges.prev.end);
    const currLabel = getPeriodLabel(ranges.curr.start, ranges.curr.end);
    
    return {
      labels,
      datasets: [
        {
          label: prevLabel,
          data: labels.map((_, i) => prevGrouped[i + 1] || 0),
          borderColor: chartColors.muted,
          backgroundColor: 'transparent',
          borderWidth: 2,
          tension: 0.4,
          pointRadius: chartGranularity === 'week' ? 3 : 1,
          pointBackgroundColor: chartColors.muted
        },
        {
          label: currLabel,
          data: labels.map((_, i) => currGrouped[i + 1] || 0),
          borderColor: chartColors.primary,
          backgroundColor: chartColors.primary + '10',
          borderWidth: 2,
          tension: 0.4,
          fill: true,
          pointRadius: chartGranularity === 'week' ? 4 : 2,
          pointBackgroundColor: chartColors.primary
        }
      ]
    };
  }, [prevData, currData, ranges, chartMetric, chartGranularity, getMetricValue, getPeriodLabel]);

  // Museum chart - only show museums with data
  const museumChart = useMemo(() => {
    const prevLabel = getPeriodLabel(ranges.prev.start, ranges.prev.end);
    const currLabel = getPeriodLabel(ranges.curr.start, ranges.curr.end);
    const allMuseums = [...new Set(data.map((r: MuseumRecord) => r.museum_name))].filter(Boolean) as string[];
    const prevByMuseum: Record<string, number> = {};
    const currByMuseum: Record<string, number> = {};
    allMuseums.forEach(m => {
      const prevRows = prevData.filter(r => r.museum_name === m);
      const currRows = currData.filter(r => r.museum_name === m);
      prevByMuseum[m] = getMetricValue(prevRows, chartMetric);
      currByMuseum[m] = getMetricValue(currRows, chartMetric);
    });
    // Only include museums that have data in either period
    const museums = allMuseums.filter(m => prevByMuseum[m] > 0 || currByMuseum[m] > 0);
    return {
      labels: museums,
      datasets: [
        { label: prevLabel, data: museums.map(m => prevByMuseum[m]), backgroundColor: chartColors.muted, borderRadius: 4 },
        { label: currLabel, data: museums.map(m => currByMuseum[m]), backgroundColor: chartColors.primary, borderRadius: 4 }
      ]
    };
  }, [data, prevData, currData, ranges, chartMetric, getMetricValue, getPeriodLabel]);

  const baseOptions = useMemo(() => createBaseOptions(showDataLabels), [showDataLabels]);

  // Map seasons to annotation bands on the current period's timeline
  const seasonAnnotations = useMemo(() => {
    if (!seasons.length) return {};
    const currStart = new Date(ranges.curr.start);
    const currEnd = new Date(ranges.curr.end);
    const annotations: Record<string, unknown> = {};
    const msPerDay = 1000 * 60 * 60 * 24;
    const granDivisor = chartGranularity === 'month' ? 30 : chartGranularity === 'week' ? 7 : 1;

    seasons.forEach((s, i) => {
      const sStart = new Date(s.StartDate);
      const sEnd = new Date(s.EndDate);
      // Check overlap with current period
      if (sEnd < currStart || sStart > currEnd) return;

      const clampedStart = sStart < currStart ? currStart : sStart;
      const clampedEnd = sEnd > currEnd ? currEnd : sEnd;
      const startIdx = Math.floor((clampedStart.getTime() - currStart.getTime()) / msPerDay / granDivisor);
      const endIdx = Math.floor((clampedEnd.getTime() - currStart.getTime()) / msPerDay / granDivisor);

      annotations[`season${i}`] = {
        type: 'box',
        xMin: startIdx - 0.5,
        xMax: endIdx + 0.5,
        backgroundColor: s.Color + '20',
        borderColor: s.Color + '40',
        borderWidth: 1,
        label: {
          display: true,
          content: `${s.Name} ${s.HijriYear}`,
          position: 'start',
          color: s.Color,
          font: { size: 10, weight: '600' },
          padding: 4
        }
      };
    });
    return annotations;
  }, [seasons, ranges.curr, chartGranularity]);

  const chartOptions: any = {
    ...baseOptions,
    plugins: {
      ...baseOptions.plugins,
      legend: { position: 'top', align: 'end', labels: { boxWidth: 12, padding: 12, font: { size: 13 } } },
      annotation: { annotations: seasonAnnotations }
    }
  };

  return (
    <div className="comparison" id="comparison-container">
      <div className="page-title-with-actions">
        <div className="page-title">
          <h1>{t('comparison.title')}</h1>
          <p>{t('comparison.subtitle')}</p>
        </div>
        <div className="header-toggles">
          <div className="toggle-with-label">
            <span className="toggle-text">{t('nav.vat') || 'VAT'}</span>
            <div className="toggle-switch">
              <button className={!includeVAT ? 'active' : ''} onClick={() => setIncludeVAT(false)}>{t('toggle.excl') || 'Excl'}</button>
              <button className={includeVAT ? 'active' : ''} onClick={() => setIncludeVAT(true)}>{t('toggle.incl') || 'Incl'}</button>
            </div>
          </div>
          <div className="toggle-with-label">
            <span className="toggle-text">{t('nav.labels')}</span>
            <div className="toggle-switch">
              <button className={!showDataLabels ? 'active' : ''} onClick={() => setShowDataLabels(false)}>{t('toggle.off')}</button>
              <button className={showDataLabels ? 'active' : ''} onClick={() => setShowDataLabels(true)}>{t('toggle.on')}</button>
            </div>
          </div>
        </div>
      </div>

      <FilterControls title={t('comparison.selectPeriod')} onReset={resetFilters}>
        <FilterControls.Row>
          <FilterControls.Group label={t('comparison.period')}>
            <select value={preset} onChange={e => setPreset(e.target.value)}>
              <option value="custom">{t('comparison.custom')}</option>
              <option value="jan">{t('months.january')}</option>
              <option value="feb">{t('months.february')}</option>
              <option value="mar">{t('months.march')}</option>
              <option value="apr">{t('months.april')}</option>
              <option value="may">{t('months.may')}</option>
              <option value="jun">{t('months.june')}</option>
              <option value="jul">{t('months.july')}</option>
              <option value="aug">{t('months.august')}</option>
              <option value="sep">{t('months.september')}</option>
              <option value="oct">{t('months.october')}</option>
              <option value="nov">{t('months.november')}</option>
              <option value="dec">{t('months.december')}</option>
              <option value="q1">{t('time.q1')}</option>
              <option value="q2">{t('time.q2')}</option>
              <option value="q3">{t('time.q3')}</option>
              <option value="q4">{t('time.q4')}</option>
              <option value="h1">{t('time.h1')}</option>
              <option value="h2">{t('time.h2')}</option>
              <option value="full">{t('time.fullYear')}</option>
              {seasons.length > 0 && (
                <optgroup label={t('comparison.seasons') || 'Seasons'}>
                  {seasons.map(s => (
                    <option key={s.Id} value={`season-${s.Id}`}>
                      {s.Name} {s.HijriYear}
                    </option>
                  ))}
                </optgroup>
              )}
            </select>
          </FilterControls.Group>
          {preset !== 'custom' && !preset.startsWith('season-') && (
            <FilterControls.Group label={t('filters.year')}>
              <select value={selectedYear} onChange={e => setSelectedYear(parseInt(e.target.value))}>
                {availableYears.map(y => (
                  <option key={y} value={y}>{y}</option>
                ))}
              </select>
            </FilterControls.Group>
          )}
          {(preset === 'custom' || preset.startsWith('season-')) && (
            <>
              <FilterControls.Group label={t('comparison.from')}>
                <input type="date" value={startDate} onChange={e => setStartDate(e.target.value)} />
              </FilterControls.Group>
              <FilterControls.Group label={t('comparison.to')}>
                <input type="date" value={endDate} onChange={e => setEndDate(e.target.value)} />
              </FilterControls.Group>
            </>
          )}
          <FilterControls.Group label={t('filters.district')}>
            <select value={filters.district} onChange={e => setFilters({...filters, district: e.target.value, museum: []})}>
              <option value="all">{t('filters.allDistricts')}</option>
              {districts.map(d => <option key={d} value={d}>{d}</option>)}
            </select>
          </FilterControls.Group>
          <FilterControls.Group label={t('filters.channel')}>
            <MultiSelect
              options={channels}
              selected={filters.channel}
              onChange={selected => setFilters({...filters, channel: selected})}
              allLabel={t('filters.allChannels')}
            />
          </FilterControls.Group>
          <FilterControls.Group label={t('filters.museum')}>
            <MultiSelect
              options={availableMuseums}
              selected={filters.museum}
              onChange={selected => setFilters({...filters, museum: selected})}
              allLabel={t('filters.allMuseums')}
            />
          </FilterControls.Group>
        </FilterControls.Row>
      </FilterControls>

      <div className="period-display-banner" id="comparison-period">
        <div className="period-box prev">
          <div className="period-label">{t('comparison.previousPeriod')}</div>
          <div className="period-value">{getPeriodLabel(ranges.prev.start, ranges.prev.end)}</div>
          <div className="period-dates">{formatDate(ranges.prev.start)} → {formatDate(ranges.prev.end)}</div>
        </div>
        <div className="period-vs">{t('comparison.vs')}</div>
        <div className="period-box curr">
          <div className="period-label">{t('comparison.currentPeriod')}</div>
          <div className="period-value">{getPeriodLabel(ranges.curr.start, ranges.curr.end)}</div>
          <div className="period-dates">{formatDate(ranges.curr.start)} → {formatDate(ranges.curr.end)}</div>
        </div>
      </div>

      {!hasData ? (
        <EmptyState 
          icon="📈"
          title={t('comparison.noData')}
          message={t('comparison.noDataMessage')}
          action={resetFilters}
          actionLabel={t('filters.reset')}
        />
      ) : (
      <>
      {/* Desktop: Grid layout */}
      <div className="comparison-grid desktop-only" id="comparison-metrics">
        {metricCards.map((card, i) => (
          <MetricCard 
            key={i}
            title={card.title} 
            prev={card.prev} 
            curr={card.curr} 
            change={card.change} 
            isCurrency={card.isCurrency}
            isPercent={card.isPercent}
            pendingMessage={card.pendingMessage}
            prevYear={getPeriodLabel(ranges.prev.start, ranges.prev.end)} 
            currYear={getPeriodLabel(ranges.curr.start, ranges.curr.end)}
          />
        ))}
      </div>

      {/* Mobile: Carousel layout */}
      <div className="cards-carousel mobile-only">
        <div className="carousel-container">
          <div className="carousel-viewport">
            <div 
              className="carousel-track"
              style={{ transform: `translateX(-${activeCard * 100}%)` }}
              onTouchStart={handleCardTouchStart}
              onTouchEnd={handleCardTouchEnd}
            >
              {metricCards.map((card, i) => (
                <div className="carousel-slide" key={i}>
                  <MetricCard 
                    title={card.title} 
                    prev={card.prev} 
                    curr={card.curr} 
                    change={card.change} 
                    isCurrency={card.isCurrency}
                    isPercent={card.isPercent}
                    pendingMessage={card.pendingMessage}
                    prevYear={getPeriodLabel(ranges.prev.start, ranges.prev.end)} 
                    currYear={getPeriodLabel(ranges.curr.start, ranges.curr.end)}
                  />
                </div>
              ))}
            </div>
          </div>
        </div>

        <div className="carousel-dots labeled">
          {metricCards.map((card, i) => (
            <button
              key={i}
              className={`carousel-dot ${activeCard === i ? 'active' : ''}`}
              onClick={() => setActiveCard(i)}
            >
              <span className="dot-label">{card.title}</span>
            </button>
          ))}
        </div>
      </div>

      {/* Desktop: Show both charts */}
      <div className="charts-grid desktop-only" id="comparison-charts">
        <div className="chart-section">
          <ExportableChart 
            filename="trend-comparison" 
            title={`${metricOptions.find(m => m.value === chartMetric)?.label} - ${t('comparison.trend')}`} 
            className="chart-container"
            controls={
              <>
                <div className="toggle-switch">
                  {granularityOptions.map(opt => (
                    <button
                      key={opt.value}
                      className={chartGranularity === opt.value ? 'active' : ''}
                      onClick={() => setChartGranularity(opt.value)}
                    >
                      {opt.label}
                    </button>
                  ))}
                </div>
                <div className="chart-metric-selector">
                  {metricOptions.map(opt => (
                    <button
                      key={opt.value}
                      className={chartMetric === opt.value ? 'active' : ''}
                      onClick={() => setChartMetric(opt.value)}
                    >
                      {opt.label}
                    </button>
                  ))}
                </div>
              </>
            }
          >
            <Line data={timeSeriesChart} options={chartOptions} />
          </ExportableChart>
        </div>
        <div className="chart-section">
          <ExportableChart 
            filename="museum-comparison" 
            title={`${metricOptions.find(m => m.value === chartMetric)?.label} - ${t('comparison.byMuseum')}`} 
            className="chart-container"
            controls={
              <div className="chart-metric-selector">
                {metricOptions.map(opt => (
                  <button
                    key={opt.value}
                    className={chartMetric === opt.value ? 'active' : ''}
                    onClick={() => setChartMetric(opt.value)}
                  >
                    {opt.label}
                  </button>
                ))}
              </div>
            }
          >
            <Bar data={museumChart} options={chartOptions} />
          </ExportableChart>
        </div>
      </div>

      {/* Mobile: Carousel */}
      <div className="charts-carousel mobile-only">
        <div className="carousel-container">
          <div className="carousel-viewport">
            <div 
              className="carousel-track" 
              style={{ transform: `translateX(-${activeChart * 100}%)` }}
              onTouchStart={handleChartTouchStart}
              onTouchEnd={handleChartTouchEnd}
            >
              <div className="carousel-slide">
                <div className="chart-section">
                  <div className="chart-header">
                    <h2>{metricOptions.find(m => m.value === chartMetric)?.label} - {t('comparison.trend')}</h2>
                    <div className="toggle-switch">
                      {granularityOptions.map(opt => (
                        <button
                          key={opt.value}
                          className={chartGranularity === opt.value ? 'active' : ''}
                          onClick={() => setChartGranularity(opt.value)}
                        >
                          {opt.label}
                        </button>
                      ))}
                    </div>
                  </div>
                  <div className="chart-selectors-inline">
                    <div className="chart-metric-selector">
                      {metricOptions.map(opt => (
                        <button
                          key={opt.value}
                          className={chartMetric === opt.value ? 'active' : ''}
                          onClick={() => setChartMetric(opt.value)}
                        >
                          {opt.label}
                        </button>
                      ))}
                    </div>
                  </div>
                  <div className="chart-container">
                    <Line data={timeSeriesChart} options={chartOptions} />
                  </div>
                </div>
              </div>
              <div className="carousel-slide">
                <div className="chart-section">
                  <div className="chart-header">
                    <h2>{metricOptions.find(m => m.value === chartMetric)?.label} - {t('comparison.byMuseum')}</h2>
                  </div>
                  <div className="chart-selectors-inline">
                    <div className="chart-metric-selector">
                      {metricOptions.map(opt => (
                        <button
                          key={opt.value}
                          className={chartMetric === opt.value ? 'active' : ''}
                          onClick={() => setChartMetric(opt.value)}
                        >
                          {opt.label}
                        </button>
                      ))}
                    </div>
                  </div>
                  <div className="chart-container">
                    <Bar data={museumChart} options={chartOptions} />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div className="carousel-dots labeled">
          {charts.map((chart, i) => (
            <button
              key={chart.id}
              className={`carousel-dot ${activeChart === i ? 'active' : ''}`}
              onClick={() => setActiveChart(i)}
            >
              <span className="dot-label">{chart.label}</span>
            </button>
          ))}
        </div>
      </div>
      </>
      )}
    </div>
  );
}

function MetricCard({ title, prev, curr, change, isCurrency, isPercent, pendingMessage, prevYear, currYear }: MetricCardProps) {
  const hasPending = prev === null || curr === null;
  const isPositive = (change ?? 0) >= 0;
  const changeText = (hasPending && pendingMessage) ? null : (change === Infinity || change === null ? '—' : `${isPositive ? '+' : ''}${change.toFixed(1)}%`);
  
  const formatValue = (val: number | null | undefined) => {
    if (val === null || val === undefined) return '—';
    if (isPercent) return val.toFixed(2) + '%';
    if (isCurrency) return formatCompactCurrency(val);
    return formatCompact(val);
  };
  
  const diff = (curr || 0) - (prev || 0);
  const diffText = (hasPending && pendingMessage) ? pendingMessage : (isPercent 
    ? (diff >= 0 ? '+' : '') + diff.toFixed(2) + 'pp'
    : (isCurrency ? formatCompactCurrency(diff) : formatCompact(diff)));
  
  return (
    <div className="metric-card">
      <h4>{title}</h4>
      <div className="metric-values">
        <div className="metric-period previous">
          <div className="year">{prevYear}</div>
          <div className="value">{formatValue(prev)}</div>
        </div>
        <div className={`metric-change ${hasPending && pendingMessage ? 'pending' : (isPositive ? 'positive' : 'negative')}`}>
          {hasPending && pendingMessage ? (
            <div className="pending-msg">{pendingMessage}</div>
          ) : (
            <>
              <div className="pct">{changeText}</div>
              <div className="abs">{diff >= 0 ? '+' : ''}{diffText}</div>
            </>
          )}
        </div>
        <div className="metric-period current">
          <div className="year">{currYear}</div>
          <div className="value">{formatValue(curr)}</div>
        </div>
      </div>
    </div>
  );
}

export default Comparison;
