'use client';

import { RangeField } from '@/components/shared/RangeField';
import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
import type { Weekday } from '@/lib/types/Weekday';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Input } from '@/ui/Input';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import {
    Calendar,
    CalendarDays,
    CalendarRange,
    ChevronDown,
    ChevronUp,
    Clock,
    Eye,
    Flag,
    Globe,
    Info,
    MapPin,
    Pencil,
    Play,
    Timer,
    Trophy,
} from 'lucide-react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';

// Common time zones for racing leagues
const TIME_ZONES = [
  { value: 'track', label: 'Track Local Time', icon: MapPin },
  { value: 'UTC', label: 'UTC', icon: Globe },
  { value: 'America/New_York', label: 'Eastern (US)', icon: Globe },
  { value: 'America/Los_Angeles', label: 'Pacific (US)', icon: Globe },
  { value: 'Europe/London', label: 'London (UK)', icon: Globe },
  { value: 'Europe/Berlin', label: 'Central Europe', icon: Globe },
  { value: 'Australia/Sydney', label: 'Sydney (AU)', icon: Globe },
];

type RecurrenceStrategy = Exclude<
  NonNullable<LeagueConfigFormModel['timings']>['recurrenceStrategy'],
  undefined
>;

interface LeagueTimingsSectionProps {
  form: LeagueConfigFormModel;
  onChange?: (form: LeagueConfigFormModel) => void;
  readOnly?: boolean;
  errors?: {
    qualifyingMinutes?: string;
    mainRaceMinutes?: string;
    roundsPlanned?: string;
  };
  title?: string;
}

// ============================================================================
// PREVIEW COMPONENTS
// ============================================================================

/** Race Day View - Shows what happens during a race day */
function RaceDayPreview({
  template,
  practiceMin,
  qualifyingMin,
  sprintMin,
  mainRaceMin,
  raceTime,
}: {
  template: string;
  practiceMin: number;
  qualifyingMin: number;
  sprintMin?: number;
  mainRaceMin: number;
  raceTime?: string;
}) {
  const hasSprint = template === 'sprintFeature' && sprintMin;
  
  // Build all possible sessions with their active status
  const allSessions = useMemo(() => {
    return [
      { name: 'Practice', duration: practiceMin, type: 'practice', active: practiceMin > 0 },
      { name: 'Qualifying', duration: qualifyingMin, type: 'qualifying', active: true },
      { name: 'Sprint Race', duration: sprintMin ?? 0, type: 'sprint', active: hasSprint },
      {
        name: template === 'endurance' ? 'Endurance Race' : hasSprint ? 'Feature Race' : 'Main Race',
        duration: mainRaceMin,
        type: 'race',
        active: true,
      },
    ];
  }, [template, practiceMin, qualifyingMin, sprintMin, mainRaceMin, hasSprint]);

  const activeSessions = allSessions.filter(s => s.active);
  const totalDuration = activeSessions.reduce((sum, s) => sum + s.duration, 0);

  // Calculate start times - use default 20:00 if not set
  const effectiveRaceTime = raceTime || '20:00';
  
  const getStartTime = (sessionIndex: number) => {
    const [hoursStr, minutesStr] = effectiveRaceTime.split(':');
    const hours = Number(hoursStr ?? '0');
    const minutes = Number(minutesStr ?? '0');
    let totalMinutes = hours * 60 + minutes;

    const active = allSessions.filter((s) => s.active);
    for (let i = 0; i < sessionIndex; i++) {
      const session = active[i];
      if (!session) continue;
      totalMinutes += session.duration + 10; // 10 min break between sessions
    }
    
    const h = Math.floor(totalMinutes / 60) % 24;
    const m = totalMinutes % 60;
    return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`;
  };

  return (
    <Stack gap={4}>
      <Stack display="flex" alignItems="center" gap={2}>
        <Icon icon={Flag} size={3.5} color="text-primary-blue" />
        <Text size="xs" weight="medium" color="text-white">Race Day Schedule</Text>
        <Text size="xs" color="text-gray-600">•</Text>
        <Icon icon={Clock} size={3} color="text-gray-400" />
        <Text size="xs" color="text-gray-400">
          Starts {effectiveRaceTime}{!raceTime && <Text as="span" color="text-gray-600" ml={1}>(default)</Text>}
        </Text>
      </Stack>

      {/* Timeline visualization - show ALL sessions */}
      <Stack gap={2}>
        {allSessions.map((session, i) => {
          const isRace = session.type === 'race' || session.type === 'sprint';
          const isActive = session.active;
          const activeIndex = isActive ? allSessions.filter((s, idx) => s.active && idx < i).length : -1;
          const startTime = isActive ? getStartTime(activeIndex) : null;
          
          return (
            <Stack
              key={session.name}
              position="relative"
              display="flex"
              alignItems="center"
              gap={3}
              p={3}
              rounded="lg"
              transition
              opacity={!isActive ? 0.4 : 1}
              bg={!isActive ? 'bg-iron-gray/10' : isRace ? 'bg-primary-blue/20' : 'bg-iron-gray/40'}
              border
              borderStyle={!isActive ? 'dashed' : 'solid'}
              borderColor={!isActive ? 'border-charcoal-outline/30' : isRace ? 'border-primary-blue/30' : 'border-charcoal-outline/50'}
              // eslint-disable-next-line gridpilot-rules/component-classification
              className={isRace && isActive ? 'bg-gradient-to-r from-primary-blue/20 to-transparent' : ''}
            >
              {/* Status badge */}
              {!isActive && (
                <Stack position="absolute" top="-1" right="-1" px={1.5} py={0.5} rounded="sm" bg="bg-charcoal-outline">
                  <Text 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '8px' }} 
                    weight="medium" 
                    color="text-gray-400"
                  >
                    Not included
                  </Text>
                </Stack>
              )}
              
              {/* Time marker */}
              <Stack w="12" textAlign="right" flexShrink={0}>
                <Text size="xs" font="mono" color={!isActive ? 'text-gray-600' : isRace ? 'text-primary-blue' : 'text-gray-400'}>
                  {startTime ?? '—'}
                </Text>
              </Stack>
              
              {/* Session indicator */}
              <Stack w="1" h="8" rounded="full" transition bg={!isActive ? 'bg-charcoal-outline/30' : isRace ? 'bg-primary-blue' : 'bg-charcoal-outline'} />
              
              {/* Session info */}
              <Stack flexGrow={1}>
                <Text size="sm" weight="medium" color={!isActive ? 'text-gray-600' : isRace ? 'text-white' : 'text-gray-300'} block>
                  {session.name}
                </Text>
                <Text 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  color="text-gray-500" 
                  block
                >
                  {isActive ? `${session.duration} minutes` : 'Disabled'}
                </Text>
              </Stack>
              
              {/* Duration bar */}
              {isActive && (
                <Stack w="16" h="2" bg="bg-charcoal-outline/50" rounded="full" overflow="hidden">
                  <Stack
                    h="full"
                    rounded="full"
                    bg={isRace ? 'bg-primary-blue' : 'bg-gray-600'}
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ width: `${(session.duration / Math.max(...activeSessions.map(s => s.duration))) * 100}%` }}
                  />
                </Stack>
              )}
            </Stack>
          );
        })}
      </Stack>

      {/* Legend */}
      <Stack display="flex" alignItems="center" justifyContent="center" gap={4} pt={2} borderTop borderColor="border-charcoal-outline/30">
        <Stack display="flex" alignItems="center" gap={1.5}>
          <Stack w="2" h="2" rounded="sm" bg="bg-primary-blue" />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-400"
          >
            Active race
          </Text>
        </Stack>
        <Stack display="flex" alignItems="center" gap={1.5}>
          <Stack w="2" h="2" rounded="sm" bg="bg-gray-600" />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-400"
          >
            Active session
          </Text>
        </Stack>
        <Stack display="flex" alignItems="center" gap={1.5}>
          <Stack w="2" h="2" rounded="sm" border borderStyle="dashed" borderColor="border-charcoal-outline/50" bg="transparent" />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            Not included
          </Text>
        </Stack>
      </Stack>

      {/* Summary */}
      <Stack display="flex" alignItems="center" justifyContent="between">
        <Stack display="flex" alignItems="center" gap={3}>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            {activeSessions.length} active sessions
          </Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            •
          </Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            {activeSessions.filter(s => s.type === 'race' || s.type === 'sprint').length} race{activeSessions.filter(s => s.type === 'race' || s.type === 'sprint').length > 1 ? 's' : ''}
          </Text>
        </Stack>
        <Stack display="flex" alignItems="center" gap={1.5} px={2} py={1} rounded="full" bg="bg-iron-gray/60">
          <Icon icon={Timer} size={3} color="text-primary-blue" />
          <Text size="xs" weight="semibold" color="text-white">
            {Math.floor(totalDuration / 60)}h {totalDuration % 60}m
          </Text>
        </Stack>
      </Stack>
    </Stack>
  );
}

/** Full Year Calendar View */
function YearCalendarPreview({
  weekdays,
  frequency,
  rounds,
  startDate,
  endDate,
}: {
  weekdays: Weekday[];
  frequency: RecurrenceStrategy;
  rounds: number;
  startDate?: string;
  endDate?: string;
}) {
  const months = [
    'Jan',
    'Feb',
    'Mar',
    'Apr',
    'May',
    'Jun',
    'Jul',
    'Aug',
    'Sep',
    'Oct',
    'Nov',
    'Dec',
  ] as const;

  const getMonthLabel = (index: number): string => months[index] ?? '—';
  
  // Parse start and end dates
  const seasonStart = useMemo(() => {
    const d = startDate ? new Date(startDate) : new Date();
    d.setHours(12, 0, 0, 0);
    return d;
  }, [startDate]);
  
  const seasonEnd = useMemo(() => {
    if (!endDate) return null;
    const d = new Date(endDate);
    d.setHours(12, 0, 0, 0);
    return d;
  }, [endDate]);
  
  // Calculate race dates based on settings
  const raceDates = useMemo(() => {
    // JavaScript getDay(): 0=Sunday, 1=Monday, 2=Tuesday, etc.
    const dayMap: Record<Weekday, number> = {
      Sun: 0,
      Mon: 1,
      Tue: 2,
      Wed: 3,
      Thu: 4,
      Fri: 5,
      Sat: 6,
    };

    // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
    const dates: Date[] = [];
    if (weekdays.length === 0 || rounds <= 0) return dates;
    
    // Convert weekday names to day numbers for faster lookup
    const selectedDayNumbers = new Set(weekdays.map(wd => dayMap[wd]));
    
    // If we have both start and end dates, evenly distribute races
    if (seasonEnd && seasonEnd > seasonStart) {
      // First, collect all possible race days between start and end
      // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
      const allPossibleDays: Date[] = [];
      const currentDate = new Date(seasonStart);
      
      while (currentDate <= seasonEnd) {
        const dayOfWeek = currentDate.getDay();
        if (selectedDayNumbers.has(dayOfWeek)) {
          // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
          allPossibleDays.push(new Date(currentDate));
        }
        currentDate.setDate(currentDate.getDate() + 1);
      }
      
      // Now evenly distribute the rounds across available days
      const totalPossible = allPossibleDays.length;
      if (totalPossible >= rounds) {
        // Space them evenly
        const spacing = totalPossible / rounds;
        for (let i = 0; i < rounds; i++) {
          const index = Math.min(Math.floor(i * spacing), totalPossible - 1);
          const chosen = allPossibleDays[index]!;
          // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
          dates.push(chosen);
        }
      } else {
        // Not enough days - use all available
        // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
        dates.push(...allPossibleDays);
      }
      
      return dates;
    }
    
    // Original algorithm: schedule based on frequency
    const currentDate = new Date(seasonStart);
    let roundsScheduled = 0;
    
    // Generate race dates for up to 2 years to ensure we can schedule all rounds
    const maxDays = 365 * 2;
    let daysChecked = 0;
    
    while (roundsScheduled < rounds && daysChecked < maxDays) {
      const dayOfWeek = currentDate.getDay();
      const isSelectedDay = selectedDayNumbers.has(dayOfWeek);
      
      // Calculate which week this is from the start
      const daysSinceStart = Math.floor((currentDate.getTime() - seasonStart.getTime()) / (24 * 60 * 60 * 1000));
      const currentWeek = Math.floor(daysSinceStart / 7);
      
      if (isSelectedDay) {
        let shouldRace = false;
        
        if (frequency === 'weekly') {
          // Weekly: race every week on selected days
          shouldRace = true;
        } else if (frequency === 'everyNWeeks') {
          // Every 2 weeks: race only on even weeks (0, 2, 4, ...)
          shouldRace = currentWeek % 2 === 0;
        } else {
          // Default to weekly if frequency not set
          shouldRace = true;
        }
        
        if (shouldRace) {
          // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
          dates.push(new Date(currentDate));
          roundsScheduled++;
        }
      }
      
      currentDate.setDate(currentDate.getDate() + 1);
      daysChecked++;
    }
    
    return dates;
  }, [weekdays, frequency, rounds, seasonStart, seasonEnd]);

  // Helper to check if a date is the season start/end
  const isSeasonStartDate = useCallback((date: Date) => {
    return date.getFullYear() === seasonStart.getFullYear() &&
           date.getMonth() === seasonStart.getMonth() &&
           date.getDate() === seasonStart.getDate();
  }, [seasonStart]);
  
  const isSeasonEndDate = useCallback((date: Date) => {
    if (!seasonEnd) return false;
    return date.getFullYear() === seasonEnd.getFullYear() &&
           date.getMonth() === seasonEnd.getMonth() &&
           date.getDate() === seasonEnd.getDate();
  }, [seasonEnd]);

  // Create year view - DYNAMIC: shows months from first race to last race + some buffer
  const yearView = useMemo(() => {
    const months = [
      'Jan',
      'Feb',
      'Mar',
      'Apr',
      'May',
      'Jun',
      'Jul',
      'Aug',
      'Sep',
      'Oct',
      'Nov',
      'Dec',
    ] as const;

    type DayInfo = {
      date: Date;
      isRace: boolean;
      dayOfMonth: number;
      isStart: boolean;
      isEnd: boolean;
      raceNumber?: number;
    };
    
    if (raceDates.length === 0) {
      // No races scheduled - show next 12 months from today
      const today = new Date();
      // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
      const view: { month: string; monthIndex: number; year: number; days: DayInfo[] }[] = [];
      
      for (let i = 0; i < 12; i++) {
        const targetMonth = (today.getMonth() + i) % 12;
        const targetYear = today.getFullYear() + Math.floor((today.getMonth() + i) / 12);
        const lastDay = new Date(targetYear, targetMonth + 1, 0);
        // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
        const days: DayInfo[] = [];
        
        for (let day = 1; day <= lastDay.getDate(); day++) {
          const date = new Date(targetYear, targetMonth, day);
          // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
          days.push({
            date,
            isRace: false,
            dayOfMonth: day,
            isStart: isSeasonStartDate(date),
            isEnd: isSeasonEndDate(date),
          });
        }
        
        // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
        view.push({
          month: months[targetMonth] ?? '—',
          monthIndex: targetMonth,
          year: targetYear,
          days
        });
      }
      
      return view;
    }
    
    // Get the range of months that contain races
    const firstRaceDate = raceDates[0]!;
    
    // Start from first race month, show 12 months total
    const startMonth = firstRaceDate.getMonth();
    const startYear = firstRaceDate.getFullYear();
    
    // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
    const view: { month: string; monthIndex: number; year: number; days: DayInfo[] }[] = [];
    
    for (let i = 0; i < 12; i++) {
      const targetMonth = (startMonth + i) % 12;
      const targetYear = startYear + Math.floor((startMonth + i) / 12);
      const lastDay = new Date(targetYear, targetMonth + 1, 0);
      // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
      const days: DayInfo[] = [];
      
      for (let day = 1; day <= lastDay.getDate(); day++) {
        const date = new Date(targetYear, targetMonth, day);
        const raceIndex = raceDates.findIndex(rd =>
          rd.getFullYear() === date.getFullYear() &&
          rd.getMonth() === date.getMonth() &&
          rd.getDate() === date.getDate()
        );
        const isRace = raceIndex >= 0;
        const raceNumber = isRace ? raceIndex + 1 : undefined;
        // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
        days.push({
          date,
          isRace,
          dayOfMonth: day,
          isStart: isSeasonStartDate(date),
          isEnd: isSeasonEndDate(date),
          ...(raceNumber !== undefined ? { raceNumber } : {}),
        });
      }
      
      // eslint-disable-next-line gridpilot-rules/component-no-data-manipulation
      view.push({
        month: months[targetMonth] ?? '—',
        monthIndex: targetMonth,
        year: targetYear,
        days
      });
    }
    
    return view;
  }, [raceDates, isSeasonStartDate, isSeasonEndDate]);

  // Calculate season stats
  const firstRace = raceDates[0];
  const lastRace = raceDates[raceDates.length - 1];
  const seasonDurationWeeks =
    firstRace && lastRace
      ? Math.ceil(
          (lastRace.getTime() - firstRace.getTime()) /
            (7 * 24 * 60 * 60 * 1000),
        )
      : 0;

  return (
    <Stack gap={4}>
      <Stack display="flex" alignItems="center" justifyContent="between">
        <Stack display="flex" alignItems="center" gap={2}>
          <Icon icon={CalendarRange} size={3.5} color="text-primary-blue" />
          <Text size="xs" weight="medium" color="text-white">Season Calendar</Text>
        </Stack>
        <Text 
          // eslint-disable-next-line gridpilot-rules/component-classification
          style={{ fontSize: '10px' }} 
          color="text-gray-500"
        >
          {raceDates.length} race{raceDates.length !== 1 ? 's' : ''} scheduled
        </Text>
      </Stack>

      {/* Year grid - 3 columns x 4 rows */}
      <Stack display="grid" gridCols={3} gap={2}>
        {yearView.map(({ month, monthIndex, year, days }) => {
          const hasRaces = days.some(d => d.isRace);
          const raceCount = days.filter(d => d.isRace).length;
          const uniqueKey = `${year}-${monthIndex}`;
          
          return (
            <Stack
              key={uniqueKey}
              rounded="lg"
              p={2}
              border
              transition
              borderColor={hasRaces ? 'border-primary-blue/30' : 'border-charcoal-outline/30'}
              bg={hasRaces ? 'bg-primary-blue/5' : 'bg-iron-gray/20'}
            >
              <Stack display="flex" alignItems="center" justifyContent="between" mb={1}>
                <Text 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  weight="medium" 
                  color={hasRaces ? 'text-white' : 'text-gray-500'}
                >
                  {month} {year !== new Date().getFullYear() && <Text as="span" color="text-gray-600">{year}</Text>}
                </Text>
                {raceCount > 0 && (
                  <Text 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '9px' }} 
                    color="text-primary-blue" 
                    weight="medium"
                  >
                    {raceCount}
                  </Text>
                )}
              </Stack>
              
              {/* Mini calendar grid */}
              <Stack display="grid" gridCols={7} gap="1px">
                {/* Fill empty days at start - getDay() returns 0 for Sunday, we want Monday first */}
                {Array.from({ length: (new Date(year, monthIndex, 1).getDay() + 6) % 7 }).map((_, i) => (
                  <Stack key={`empty-${uniqueKey}-${i}`} w="2" h="2" />
                ))}
                
                {days.map(({ dayOfMonth, isRace, isStart, isEnd, raceNumber }) => (
                  <Stack
                    key={`${uniqueKey}-${dayOfMonth}`}
                    w="2"
                    h="2"
                    rounded="sm"
                    position="relative"
                    bg={
                      isStart ? 'bg-performance-green' :
                      isEnd ? 'bg-warning-amber' :
                      isRace ? 'bg-primary-blue' :
                      'bg-charcoal-outline/30'
                    }
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    className={`
                      ${isStart ? 'shadow-[0_0_6px_rgba(111,227,122,0.8)] ring-1 ring-performance-green' : ''}
                      ${isEnd ? 'shadow-[0_0_6px_rgba(255,197,86,0.8)] ring-1 ring-warning-amber' : ''}
                      ${isRace && !isStart && !isEnd ? 'shadow-[0_0_4px_rgba(25,140,255,0.6)]' : ''}
                    `}
                    title={
                      isStart ? `Season Start: ${month} ${dayOfMonth}, ${year}` :
                      isEnd ? `Season End: ${month} ${dayOfMonth}, ${year}` :
                      isRace ? `Round ${raceNumber}: ${month} ${dayOfMonth}, ${year}` :
                      undefined
                    }
                  />
                ))}
              </Stack>
            </Stack>
          );
        })}
      </Stack>

      {/* Season summary */}
      <Stack display="grid" gridCols={3} gap={2} pt={2} borderTop borderColor="border-charcoal-outline/30">
        <Stack textAlign="center">
          <Text size="lg" weight="bold" color="text-white" block>{rounds}</Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '9px' }} 
            color="text-gray-500" 
            block
          >
            Rounds
          </Text>
        </Stack>
        <Stack textAlign="center">
          <Text size="lg" weight="bold" color="text-white" block>
            {seasonDurationWeeks || '—'}
          </Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '9px' }} 
            color="text-gray-500" 
            block
          >
            Weeks
          </Text>
        </Stack>
        <Stack textAlign="center">
          <Text size="lg" weight="bold" color="text-primary-blue" block>
            {firstRace && lastRace
              ? `${getMonthLabel(firstRace.getMonth())}–${getMonthLabel(
                  lastRace.getMonth(),
                )}`
              : '—'}
          </Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '9px' }} 
            color="text-gray-500" 
            block
          >
            Duration
          </Text>
        </Stack>
      </Stack>

      {/* Legend */}
      <Stack display="flex" alignItems="center" justifyContent="center" gap={3} flexWrap="wrap">
        <Stack display="flex" alignItems="center" gap={1}>
          <Stack w="2" h="2" rounded="sm" bg="bg-performance-green" 
            // eslint-disable-next-line gridpilot-rules/component-classification
            className="ring-1 ring-performance-green" 
          />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            Start
          </Text>
        </Stack>
        <Stack display="flex" alignItems="center" gap={1}>
          <Stack w="2" h="2" rounded="sm" bg="bg-primary-blue" />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            Race
          </Text>
        </Stack>
        {seasonEnd && (
          <Stack display="flex" alignItems="center" gap={1}>
            <Stack w="2" h="2" rounded="sm" bg="bg-warning-amber" 
              // eslint-disable-next-line gridpilot-rules/component-classification
              className="ring-1 ring-warning-amber" 
            />
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }} 
              color="text-gray-500"
            >
              End
            </Text>
          </Stack>
        )}
        <Stack display="flex" alignItems="center" gap={1}>
          <Stack w="2" h="2" rounded="sm" bg="bg-charcoal-outline/30" />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500"
          >
            No race
          </Text>
        </Stack>
      </Stack>
    </Stack>
  );
}

/** Season Stats Overview */
function SeasonStatsPreview({
  rounds,
  weekdays,
  frequency,
  weekendTemplate,
  practiceMin,
  qualifyingMin,
  sprintMin,
  mainRaceMin,
}: {
  rounds: number;
  weekdays: Weekday[];
  frequency: RecurrenceStrategy;
  weekendTemplate: string;
  practiceMin: number;
  qualifyingMin: number;
  sprintMin?: number;
  mainRaceMin: number;
}) {
  const hasSprint = weekendTemplate === 'sprintFeature';
  const sessionsPerRound = 2 + (hasSprint ? 2 : 1); // practice + quali + race(s)
  const totalSessions = rounds * sessionsPerRound;
  const raceMinutesPerRound = (hasSprint ? (sprintMin ?? 0) : 0) + mainRaceMin;
  const totalRaceMinutes = rounds * raceMinutesPerRound;
  const totalMinutesPerRound = practiceMin + qualifyingMin + raceMinutesPerRound;

  // Estimate season duration
  const racesPerWeek = frequency === 'weekly' ? weekdays.length : weekdays.length / 2;
  const weeksNeeded = Math.ceil(rounds / Math.max(racesPerWeek, 0.5));

  return (
    <Stack gap={4}>
      <Stack display="flex" alignItems="center" gap={2}>
        <Icon icon={Trophy} size={3.5} color="text-primary-blue" />
        <Text size="xs" weight="medium" color="text-white">Season Statistics</Text>
      </Stack>

      {/* Visual rounds */}
      <Stack gap={2}>
        <Stack display="flex" alignItems="center" gap={1} flexWrap="wrap">
          {Array.from({ length: Math.min(rounds, 20) }).map((_, i) => (
            <Stack
              key={i}
              w="5"
              h="5"
              rounded="sm"
              display="flex"
              alignItems="center"
              justifyContent="center"
              transition
              bg={
                i === 0 ? 'bg-performance-green' :
                i === rounds - 1 ? 'bg-primary-blue' :
                'bg-iron-gray/60'
              }
              border
              borderColor={
                i === 0 ? 'border-performance-green' :
                i === rounds - 1 ? 'border-primary-blue' :
                'border-charcoal-outline'
              }
              color="text-white"
              // eslint-disable-next-line gridpilot-rules/component-classification
              className={i !== 0 && i !== rounds - 1 ? 'text-gray-500 hover:border-primary-blue/50' : ''}
            >
              <Text 
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ fontSize: '8px' }} 
                weight="bold"
              >
                {i + 1}
              </Text>
            </Stack>
          ))}
          {rounds > 20 && (
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }} 
              color="text-gray-500" 
              ml={1}
            >
              +{rounds - 20}
            </Text>
          )}
        </Stack>
        <Stack display="flex" alignItems="center" gap={3}>
          <Stack display="flex" alignItems="center" gap={1}>
            <Stack w="2" h="2" rounded="sm" bg="bg-performance-green" />
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }} 
              color="text-gray-500"
            >
              Season start
            </Text>
          </Stack>
          <Stack display="flex" alignItems="center" gap={1}>
            <Stack w="2" h="2" rounded="sm" bg="bg-primary-blue" />
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }} 
              color="text-gray-500"
            >
              Finale
            </Text>
          </Stack>
        </Stack>
      </Stack>

      {/* Stats grid */}
      <Stack display="grid" gridCols={2} gap={2}>
        <Stack rounded="lg" bg="bg-iron-gray/30" border borderColor="border-charcoal-outline/50" p={3}>
          <Text size="2xl" weight="bold" color="text-white" block>{totalSessions}</Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500" 
            block
          >
            Total sessions
          </Text>
        </Stack>
        <Stack rounded="lg" bg="bg-iron-gray/30" border borderColor="border-charcoal-outline/50" p={3}>
          <Text size="2xl" weight="bold" color="text-white" block>{Math.round(totalRaceMinutes / 60)}h</Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500" 
            block
          >
            Racing time
          </Text>
        </Stack>
        <Stack rounded="lg" bg="bg-iron-gray/30" border borderColor="border-charcoal-outline/50" p={3}>
          <Text size="2xl" weight="bold" color="text-white" block>~{weeksNeeded}</Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500" 
            block
          >
            Weeks duration
          </Text>
        </Stack>
        <Stack rounded="lg" bg="bg-iron-gray/30" border borderColor="border-charcoal-outline/50" p={3}>
          <Text size="2xl" weight="bold" color="text-white" block>{totalMinutesPerRound}</Text>
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500" 
            block
          >
            min/race day
          </Text>
        </Stack>
      </Stack>
    </Stack>
  );
}

// ============================================================================
// INLINE EDITABLE ROUNDS COMPONENT
// ============================================================================

function InlineEditableRounds({
  value,
  onChange,
  min,
  max,
}: {
  value: number;
  onChange: (value: number) => void;
  min: number;
  max: number;
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(value.toString());
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (isEditing && inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [isEditing]);

  const handleSubmit = () => {
    const num = parseInt(editValue, 10);
    if (!isNaN(num) && num >= min && num <= max) {
      onChange(num);
    } else {
      setEditValue(value.toString());
    }
    setIsEditing(false);
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      handleSubmit();
    } else if (e.key === 'Escape') {
      setEditValue(value.toString());
      setIsEditing(false);
    }
  };

  return (
    <Stack display="flex" alignItems="center" gap={4} p={4} rounded="xl" 
      // eslint-disable-next-line gridpilot-rules/component-classification
      className="bg-gradient-to-br from-iron-gray/60 to-iron-gray/30 border border-charcoal-outline"
    >
      {isEditing ? (
        <Stack
          as="input"
          ref={inputRef}
          type="number"
          min={min}
          max={max}
          value={editValue}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => setEditValue(e.target.value)}
          onBlur={handleSubmit}
          onKeyDown={handleKeyDown}
          w="20"
          bg="transparent"
          borderBottom
          borderWidth="2px"
          borderColor="border-primary-blue"
          color="text-white"
          textAlign="center"
          weight="bold"
          // eslint-disable-next-line gridpilot-rules/component-classification
          className="text-4xl outline-none"
        />
      ) : (
        <Stack
          as="button"
          type="button"
          onClick={() => {
            setEditValue(value.toString());
            setIsEditing(true);
          }}
          display="flex"
          alignItems="center"
          gap={2}
          color="text-white"
          hoverTextColor="text-primary-blue"
          transition
          group
          // eslint-disable-next-line gridpilot-rules/component-classification
          className="text-4xl font-bold"
        >
          {value}
          <Icon icon={Pencil} size={4} opacity={0} 
            // eslint-disable-next-line gridpilot-rules/component-classification
            className="group-hover:opacity-100 text-primary-blue transition-opacity" 
          />
        </Stack>
      )}
      <Stack flexGrow={1}>
        <Text size="sm" weight="medium" color="text-gray-300" block>rounds</Text>
        <Text 
          // eslint-disable-next-line gridpilot-rules/component-classification
          style={{ fontSize: '10px' }} 
          color="text-gray-500" 
          block
        >
          Click to edit
        </Text>
      </Stack>
      <Stack display="flex" flexDirection="col" gap={1}>
        <Stack
          as="button"
          type="button"
          onClick={() => onChange(Math.min(value + 1, max))}
          disabled={value >= max}
          p={1.5}
          rounded="sm"
          bg="bg-iron-gray/60"
          border
          borderColor="border-charcoal-outline"
          hoverBorderColor="border-primary-blue"
          transition
          opacity={value >= max ? 0.3 : 1}
          cursor={value >= max ? 'not-allowed' : 'pointer'}
        >
          <Icon icon={ChevronUp} size={4} color="text-gray-400" />
        </Stack>
        <Stack
          as="button"
          type="button"
          onClick={() => onChange(Math.max(value - 1, min))}
          disabled={value <= min}
          p={1.5}
          rounded="sm"
          bg="bg-iron-gray/60"
          border
          borderColor="border-charcoal-outline"
          hoverBorderColor="border-primary-blue"
          transition
          opacity={value <= min ? 0.3 : 1}
          cursor={value <= min ? 'not-allowed' : 'pointer'}
        >
          <Icon icon={ChevronDown} size={4} color="text-gray-400" />
        </Stack>
      </Stack>
    </Stack>
  );
}

// ============================================================================
// COLLAPSIBLE SECTION COMPONENT
// ============================================================================

interface CollapsibleSectionProps {
  icon: React.ReactNode;
  title: string;
  description?: string;
  defaultOpen?: boolean;
  children: React.ReactNode;
}

function CollapsibleSection({
  icon,
  title,
  description,
  defaultOpen = false,
  children,
}: CollapsibleSectionProps) {
  const [isOpen, setIsOpen] = useState(defaultOpen);

  return (
    <Stack rounded="xl" border borderColor="border-charcoal-outline/50" bg="bg-iron-gray/20" overflow="hidden" transition>
      <Stack
        as="button"
        type="button"
        onClick={() => setIsOpen(!isOpen)}
        w="full"
        display="flex"
        alignItems="center"
        justifyContent="between"
        p={4}
        transition
        hoverBg="bg-iron-gray/30"
      >
        <Stack display="flex" alignItems="center" gap={3}>
          <Stack display="flex" h="8" w="8" alignItems="center" justifyContent="center" rounded="lg" bg="bg-primary-blue/10" flexShrink={0}>
            {icon}
          </Stack>
          <Stack textAlign="left">
            <Heading level={3} fontSize="sm" weight="semibold" color="text-white">{title}</Heading>
            {description && (
              <Text size="xs" color="text-gray-500" mt={0.5} block>{description}</Text>
            )}
          </Stack>
        </Stack>
        <Stack transform transition 
          // eslint-disable-next-line gridpilot-rules/component-classification
          className={isOpen ? 'rotate-180' : ''}
        >
          <Icon icon={ChevronDown} size={4} color="text-gray-400" />
        </Stack>
      </Stack>
      <Stack
        transition
        // eslint-disable-next-line gridpilot-rules/component-classification
        className={`ease-in-out ${
          isOpen ? 'max-h-[2000px] opacity-100' : 'max-h-0 opacity-0 overflow-hidden'
        }`}
      >
        <Stack px={4} pb={4} pt={2} borderTop borderColor="border-charcoal-outline/30">
          {children}
        </Stack>
      </Stack>
    </Stack>
  );
}

// ============================================================================
// MAIN COMPONENT
// ============================================================================

export function LeagueTimingsSection({
  form,
  onChange,
  readOnly,
  errors,
}: LeagueTimingsSectionProps) {
  const disabled = readOnly || !onChange;
  const timings = form.timings;

  const [showAdvanced, setShowAdvanced] = useState(false);
  const [previewTab, setPreviewTab] = useState<'day' | 'year' | 'stats'>('day');

  const updateTimings = (
    patch: Partial<NonNullable<LeagueConfigFormModel['timings']>>,
  ) => {
    if (!onChange) return;
    onChange({
      ...form,
      timings: {
        ...timings,
        ...patch,
      },
    });
  };

  const handleRoundsChange = (value: number) => {
    if (!onChange) return;
    updateTimings({ roundsPlanned: value });
  };

  // Show sprint race field if sprintRaceMinutes is set (will be derived from scoring pattern)
  const showSprint =
    typeof timings.sprintRaceMinutes === 'number' && timings.sprintRaceMinutes > 0;

  const recurrenceStrategy: RecurrenceStrategy =
    timings.recurrenceStrategy ?? 'weekly';

  const weekdays: Weekday[] = (timings.weekdays ?? []) as Weekday[];

  const handleWeekdayToggle = (day: Weekday) => {
    const current = new Set(weekdays);
    if (current.has(day)) {
      current.delete(day);
    } else {
      current.add(day);
    }
    updateTimings({ weekdays: Array.from(current) });
  };

  // Read-only view
  if (disabled) {
    return (
      <Stack gap={4}>
        <Heading level={3} fontSize="lg" weight="semibold" color="text-white">Schedule & timings</Heading>
        <Stack gap={3}>
          <Stack>
            <Text weight="medium" color="text-gray-200">Planned rounds:</Text>{' '}
            <Text color="text-gray-300">{timings.roundsPlanned ?? '—'}</Text>
          </Stack>
        </Stack>
      </Stack>
    );
  }

  const allWeekdays: { day: Weekday; label: string; short: string }[] = [
    { day: 'Mon', label: 'Monday', short: 'Mon' },
    { day: 'Tue', label: 'Tuesday', short: 'Tue' },
    { day: 'Wed', label: 'Wednesday', short: 'Wed' },
    { day: 'Thu', label: 'Thursday', short: 'Thu' },
    { day: 'Fri', label: 'Friday', short: 'Fri' },
    { day: 'Sat', label: 'Saturday', short: 'Sat' },
    { day: 'Sun', label: 'Sunday', short: 'Sun' },
  ];

  return (
    <Stack display="grid" responsiveGridCols={{ base: 1, lg: 2 }} gap={6}>
      {/* LEFT COLUMN: Configuration */}
      <Stack gap={4}>
        {/* Session Durations - Collapsible */}
        <CollapsibleSection
          icon={<Icon icon={Timer} size={4} color="text-primary-blue" />}
          title="Session Durations"
          description="Configure practice, qualifying, and race lengths"
          defaultOpen={false}
        >
          <Stack display="grid" gridCols={2} gap={3}>
            <RangeField
              label="Practice"
              value={timings.practiceMinutes ?? 20}
              min={0}
              max={60}
              onChange={(v: number) => updateTimings({ practiceMinutes: v })}
              unitLabel="min"
              compact
            />
            <RangeField
              label="Qualifying"
              value={timings.qualifyingMinutes ?? 15}
              min={5}
              max={30}
              onChange={(v: number) => updateTimings({ qualifyingMinutes: v })}
              unitLabel="min"
              compact
              error={errors?.qualifyingMinutes}
            />
            {showSprint && (
              <RangeField
                label="Sprint Race"
                value={timings.sprintRaceMinutes ?? 20}
                min={10}
                max={45}
                onChange={(v: number) => updateTimings({ sprintRaceMinutes: v })}
                unitLabel="min"
                compact
              />
            )}
            <RangeField
              label={showSprint ? 'Feature Race' : 'Main Race'}
              value={timings.mainRaceMinutes ?? 40}
              min={15}
              max={180}
              onChange={(v: number) => updateTimings({ mainRaceMinutes: v })}
              unitLabel="min"
              compact
              error={errors?.mainRaceMinutes}
            />
          </Stack>
        </CollapsibleSection>

        {/* Season Length - Collapsible */}
        <CollapsibleSection
          icon={<Icon icon={Trophy} size={4} color="text-primary-blue" />}
          title="Season Length"
          description={`${timings.roundsPlanned ?? 8} rounds planned`}
          defaultOpen={false}
        >
          <InlineEditableRounds
            value={timings.roundsPlanned ?? 8}
            onChange={handleRoundsChange}
            min={4}
            max={24}
          />
          <Text 
            // eslint-disable-next-line gridpilot-rules/component-classification
            style={{ fontSize: '10px' }} 
            color="text-gray-500" 
            mt={2} 
            block
          >
            Each round is one complete race day. Click the number to edit directly.
          </Text>
        </CollapsibleSection>

        {/* Race Schedule - Collapsible */}
        <CollapsibleSection
          icon={<Icon icon={CalendarDays} size={4} color="text-primary-blue" />}
          title="Race Schedule"
          description="Weekly/bi-weekly and race days"
          defaultOpen={false}
        >
          {/* Frequency */}
          <Stack gap={2} mb={4}>
            <Text as="label" size="xs" color="text-gray-400" block>How often?</Text>
            <Stack display="flex" gap={2}>
              {[
                { id: 'weekly', label: 'Weekly' },
                { id: 'everyNWeeks', label: 'Every 2 weeks' },
              ].map((opt) => {
                const isSelected =
                  (opt.id === 'weekly' && recurrenceStrategy === 'weekly') ||
                  (opt.id === 'everyNWeeks' && recurrenceStrategy === 'everyNWeeks');
                return (
                  <Stack
                    key={opt.id}
                    as="button"
                    type="button"
                    onClick={() =>
                      updateTimings({
                        recurrenceStrategy: opt.id as RecurrenceStrategy,
                        ...(opt.id === 'everyNWeeks'
                          ? { intervalWeeks: 2 }
                          : {}),
                      })
                    }
                    flexGrow={1}
                    px={3}
                    py={2}
                    rounded="lg"
                    border
                    transition
                    borderColor={isSelected ? 'border-primary-blue' : 'border-charcoal-outline'}
                    bg={isSelected ? 'bg-primary-blue/10' : 'bg-iron-gray/30'}
                    color={isSelected ? 'text-white' : 'text-gray-400'}
                    hoverBorderColor={!isSelected ? 'border-gray-500' : undefined}
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '12px', fontWeight: 500 }}
                  >
                    {opt.label}
                  </Stack>
                );
              })}
            </Stack>
          </Stack>

          {/* Day selection */}
          <Stack gap={2}>
            <Stack display="flex" alignItems="center" justifyContent="between">
              <Text as="label" size="xs" color="text-gray-400">Which days?</Text>
              {weekdays.length === 0 && (
                <Text 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  color="text-warning-amber"
                >
                  Select at least one
                </Text>
              )}
            </Stack>

            <Stack display="flex" gap={1}>
              {allWeekdays.map(({ day, short }) => {
                const isSelected = weekdays.includes(day);
                return (
                  <Stack
                    key={day}
                    as="button"
                    type="button"
                    onClick={() => handleWeekdayToggle(day)}
                    flexGrow={1}
                    py={2}
                    rounded="lg"
                    border
                    transition
                    borderColor={isSelected ? 'border-primary-blue' : 'border-charcoal-outline'}
                    bg={isSelected ? 'bg-primary-blue' : 'bg-iron-gray/30'}
                    color={isSelected ? 'text-white' : 'text-gray-500'}
                    shadow={isSelected ? '0_0_8px_rgba(25,140,255,0.4)' : undefined}
                    hoverBorderColor={!isSelected ? 'border-gray-500' : undefined}
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '10px', fontWeight: 500 }}
                  >
                    {short}
                  </Stack>
                );
              })}
            </Stack>
          </Stack>
        </CollapsibleSection>

        {/* Season Duration - Collapsible */}
        <CollapsibleSection
          icon={<Icon icon={Calendar} size={4} color="text-primary-blue" />}
          title="Season Duration"
          description="Start/end dates and time settings"
          defaultOpen={false}
        >
          <Stack gap={4}>
            <Stack display="grid" gridCols={2} gap={3}>
              <Stack gap={1.5}>
                <Text as="label" 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  color="text-gray-400" 
                  weight="medium" 
                  display="flex" 
                  alignItems="center" 
                  gap={1}
                >
                  <Stack w="2" h="2" rounded="sm" bg="bg-performance-green" />
                  Season Start
                </Text>
                <Input
                  type="date"
                  value={timings.seasonStartDate ?? ''}
                  onChange={(e: React.ChangeEvent<HTMLInputElement>) => updateTimings({ seasonStartDate: e.target.value })}
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  className="bg-iron-gray/30"
                />
              </Stack>
              <Stack gap={1.5}>
                <Text as="label" 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  color="text-gray-400" 
                  weight="medium" 
                  display="flex" 
                  alignItems="center" 
                  gap={1}
                >
                  <Stack w="2" h="2" rounded="sm" bg="bg-warning-amber" />
                  Season End
                </Text>
                <Input
                  type="date"
                  value={timings.seasonEndDate ?? ''}
                  onChange={(e: React.ChangeEvent<HTMLInputElement>) => updateTimings({ seasonEndDate: e.target.value })}
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  className="bg-iron-gray/30"
                />
              </Stack>
            </Stack>
            
            {timings.seasonStartDate && timings.seasonEndDate && (
              <Stack display="flex" alignItems="start" gap={2} p={2} rounded="lg" bg="bg-primary-blue/5" border borderColor="border-primary-blue/20">
                <Icon icon={Info} size={3.5} color="text-primary-blue" mt={0.5} flexShrink={0} />
                <Text 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }} 
                  color="text-gray-400"
                >
                  Races will be <Text as="span" color="text-white" weight="medium">evenly distributed</Text> between start and end dates on your selected race days.
                </Text>
              </Stack>
            )}

            <Stack gap={1.5}>
              <Text as="label" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ fontSize: '10px' }} 
                color="text-gray-400" 
                weight="medium"
              >
                Race Start Time
              </Text>
              <Input
                type="time"
                value={timings.raceStartTime ?? '20:00'}
                onChange={(e: React.ChangeEvent<HTMLInputElement>) => updateTimings({ raceStartTime: e.target.value })}
                // eslint-disable-next-line gridpilot-rules/component-classification
                className="bg-iron-gray/30"
              />
            </Stack>

            {/* Time Zone Selector */}
            <Stack gap={1.5}>
              <Text as="label" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ fontSize: '10px' }} 
                color="text-gray-400" 
                weight="medium"
              >
                Time Zone
              </Text>
              <Stack display="grid" gridCols={2} gap={2}>
                {TIME_ZONES.slice(0, 2).map((tz) => {
                  const isSelected = (timings.timezoneId ?? 'UTC') === tz.value;
                  const TzIcon = tz.icon;
                  return (
                    <Stack
                      key={tz.value}
                      as="button"
                      type="button"
                      onClick={() => updateTimings({ timezoneId: tz.value })}
                      display="flex"
                      alignItems="center"
                      gap={2}
                      px={3}
                      py={2.5}
                      rounded="lg"
                      border
                      transition
                      borderColor={isSelected ? (tz.value === 'track' ? 'border-performance-green' : 'border-primary-blue') : 'border-charcoal-outline'}
                      bg={isSelected ? (tz.value === 'track' ? 'bg-performance-green/10' : 'bg-primary-blue/10') : 'bg-iron-gray/30'}
                      shadow={isSelected ? '0_0_12px_rgba(25,140,255,0.2)' : undefined}
                      hoverBorderColor={!isSelected ? 'border-gray-500' : undefined}
                      textAlign="left"
                    >
                      <Icon icon={TzIcon} size={4} color={isSelected ? (tz.value === 'track' ? 'text-performance-green' : 'text-primary-blue') : 'text-gray-400'} />
                      <Stack flexGrow={1}>
                        <Text size="xs" weight="medium" color={isSelected ? 'text-white' : 'text-gray-300'} block>
                          {tz.label}
                        </Text>
                        {tz.value === 'track' && (
                          <Text 
                            // eslint-disable-next-line gridpilot-rules/component-classification
                            style={{ fontSize: '9px' }} 
                            color="text-gray-500" 
                            block
                          >
                            Adjusts per track
                          </Text>
                        )}
                      </Stack>
                    </Stack>
                  );
                })}
              </Stack>
              
              {/* More time zones - expandable */}
              <Stack
                as="button"
                type="button"
                onClick={() => setShowAdvanced(!showAdvanced)}
                display="flex"
                alignItems="center"
                gap={1.5}
                transition
                color="text-gray-400"
                hoverTextColor="text-white"
              >
                <Icon icon={showAdvanced ? ChevronUp : ChevronDown} size={3} />
                <Text 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '10px' }}
                >
                  {showAdvanced ? 'Hide' : 'Show'} more time zones
                </Text>
              </Stack>
              
              {showAdvanced && (
                <Stack display="grid" gridCols={2} gap={2} mt={2}>
                  {TIME_ZONES.slice(2).map((tz) => {
                    const isSelected = (timings.timezoneId ?? 'UTC') === tz.value;
                    const TzIcon = tz.icon;
                    return (
                      <Stack
                        key={tz.value}
                        as="button"
                        type="button"
                        onClick={() => updateTimings({ timezoneId: tz.value })}
                        display="flex"
                        alignItems="center"
                        gap={2}
                        px={3}
                        py={2}
                        rounded="lg"
                        border
                        transition
                        borderColor={isSelected ? 'border-primary-blue' : 'border-charcoal-outline'}
                        bg={isSelected ? 'bg-primary-blue/10' : 'bg-iron-gray/30'}
                        hoverBorderColor={!isSelected ? 'border-gray-500' : undefined}
                        textAlign="left"
                      >
                        <Icon icon={TzIcon} size={3.5} color={isSelected ? 'text-primary-blue' : 'text-gray-500'} />
                        <Text size="xs" color={isSelected ? 'text-white' : 'text-gray-400'}>{tz.label}</Text>
                      </Stack>
                    );
                  })}
                </Stack>
              )}
            </Stack>
            
            <Stack display="flex" alignItems="start" gap={2} p={2} rounded="lg" bg="bg-performance-green/5" border borderColor="border-performance-green/20">
              <Icon icon={Info} size={3.5} color="text-performance-green" mt={0.5} flexShrink={0} />
              <Text 
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ fontSize: '10px' }} 
                color="text-gray-400"
              >
                {(timings.timezoneId ?? 'UTC') === 'track'
                  ? 'Track Local Time means race times will be displayed in each track\'s local time zone. Great for immersive scheduling!'
                  : 'All race times will be displayed in the selected time zone for consistency.'
                }
              </Text>
            </Stack>
          </Stack>
        </CollapsibleSection>
      </Stack>

      {/* RIGHT COLUMN: Live Preview */}
      <Stack gap={4}>
        <Stack 
          // eslint-disable-next-line gridpilot-rules/component-classification
          style={{ position: 'sticky', top: '1rem' }}
        >
          <Stack rounded="xl" border borderColor="border-charcoal-outline" 
            // eslint-disable-next-line gridpilot-rules/component-classification
            className="bg-gradient-to-br from-iron-gray/80 to-deep-graphite" 
            overflow="hidden"
          >
            {/* Preview header with tabs */}
            <Stack display="flex" alignItems="center" justifyContent="between" p={3} borderBottom borderColor="border-charcoal-outline/50" bg="bg-deep-graphite/50">
              <Stack display="flex" alignItems="center" gap={2}>
                <Icon icon={Eye} size={4} color="text-primary-blue" />
                <Text size="xs" weight="semibold" color="text-white">Preview</Text>
              </Stack>
              <Stack display="flex" gap={1} p={0.5} rounded="lg" bg="bg-iron-gray/60">
                {[
                  { id: 'day', label: 'Race Day', icon: Play },
                  { id: 'year', label: 'Calendar', icon: CalendarRange },
                  { id: 'stats', label: 'Stats', icon: Trophy },
                ].map((tab) => (
                  <Stack
                    key={tab.id}
                    as="button"
                    type="button"
                    onClick={() => setPreviewTab(tab.id as typeof previewTab)}
                    display="flex"
                    alignItems="center"
                    gap={1}
                    px={2}
                    py={1}
                    rounded="sm"
                    transition
                    bg={previewTab === tab.id ? 'bg-primary-blue' : undefined}
                    color={previewTab === tab.id ? 'text-white' : 'text-gray-400'}
                    hoverTextColor={previewTab !== tab.id ? 'text-white' : undefined}
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '10px', fontWeight: 500 }}
                  >
                    <Icon icon={tab.icon} size={3} />
                    <Stack as="span" 
                      // eslint-disable-next-line gridpilot-rules/component-classification
                      className="hidden sm:inline"
                    >
                      {tab.label}
                    </Stack>
                  </Stack>
                ))}
              </Stack>
            </Stack>

            {/* Preview content */}
            <Stack p={4} 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ minHeight: '300px' }}
            >
              {previewTab === 'day' && (() => {
                const sprintMinutes = showSprint
                  ? timings.sprintRaceMinutes ?? 20
                  : undefined;
                return (
                  <RaceDayPreview
                    template={showSprint ? 'sprintFeature' : 'feature'}
                    practiceMin={timings.practiceMinutes ?? 20}
                    qualifyingMin={timings.qualifyingMinutes ?? 15}
                    {...(sprintMinutes !== undefined
                      ? { sprintMin: sprintMinutes }
                      : {})}
                    mainRaceMin={timings.mainRaceMinutes ?? 40}
                    {...(timings.raceStartTime
                      ? { raceTime: timings.raceStartTime }
                      : {})}
                  />
                );
              })()}

              {previewTab === 'year' && (
                <YearCalendarPreview
                  weekdays={weekdays}
                  frequency={recurrenceStrategy}
                  rounds={timings.roundsPlanned ?? 8}
                  {...(timings.seasonStartDate
                    ? { startDate: timings.seasonStartDate }
                    : {})}
                  {...(timings.seasonEndDate
                    ? { endDate: timings.seasonEndDate }
                    : {})}
                />
              )}

              {previewTab === 'stats' && (() => {
                const sprintMinutes = showSprint
                  ? timings.sprintRaceMinutes ?? 20
                  : undefined;
                return (
                  <SeasonStatsPreview
                    rounds={timings.roundsPlanned ?? 8}
                    weekdays={weekdays}
                    frequency={recurrenceStrategy}
                    weekendTemplate={showSprint ? 'sprintFeature' : 'feature'}
                    practiceMin={timings.practiceMinutes ?? 20}
                    qualifyingMin={timings.qualifyingMinutes ?? 15}
                    {...(sprintMinutes !== undefined
                      ? { sprintMin: sprintMinutes }
                      : {})}
                    mainRaceMin={timings.mainRaceMinutes ?? 40}
                  />
                );
              })()}
            </Stack>
          </Stack>

          {/* Helper tip */}
          <Stack mt={3} display="flex" alignItems="start" gap={2} p={3} rounded="lg" bg="bg-primary-blue/5" border borderColor="border-primary-blue/20">
            <Icon icon={Info} size={4} color="text-primary-blue" mt={0.5} flexShrink={0} />
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '11px' }} 
              color="text-gray-400" 
              leading="relaxed"
            >
              Preview updates live as you configure. Check <Text as="span" color="text-white" weight="medium">Race Day</Text> for session timing, <Text as="span" color="text-white" weight="medium">Calendar</Text> for the full year view, and <Text as="span" color="text-white" weight="medium">Stats</Text> for season totals.
            </Text>
          </Stack>
        </Stack>
      </Stack>
    </Stack>
  );
}