'use client';

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

// 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 (
    <div className="space-y-4">
      <div className="flex items-center gap-2 text-xs text-gray-400">
        <Flag className="w-3.5 h-3.5 text-primary-blue" />
        <span className="font-medium text-white">Race Day Schedule</span>
        <span className="text-gray-600">•</span>
        <Clock className="w-3 h-3" />
        <span>Starts {effectiveRaceTime}{!raceTime && <span className="text-gray-600 ml-1">(default)</span>}</span>
      </div>

      {/* Timeline visualization - show ALL sessions */}
      <div className="space-y-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 (
            <div
              key={session.name}
              className={`
                relative flex items-center gap-3 p-3 rounded-lg transition-all duration-200
                ${!isActive
                  ? 'opacity-40 bg-iron-gray/10 border border-dashed border-charcoal-outline/30'
                  : isRace
                    ? 'bg-gradient-to-r from-primary-blue/20 to-transparent border border-primary-blue/30'
                    : 'bg-iron-gray/40 border border-charcoal-outline/50'
                }
              `}
            >
              {/* Status badge */}
              {!isActive && (
                <div className="absolute -top-1 -right-1 px-1.5 py-0.5 rounded text-[8px] font-medium bg-charcoal-outline text-gray-400">
                  Not included
                </div>
              )}
              
              {/* Time marker */}
              <div className="w-12 text-right shrink-0">
                <span className={`text-xs font-mono ${!isActive ? 'text-gray-600' : isRace ? 'text-primary-blue' : 'text-gray-400'}`}>
                  {startTime ?? '—'}
                </span>
              </div>
              
              {/* Session indicator */}
              <div className={`w-1 h-8 rounded-full transition-colors ${!isActive ? 'bg-charcoal-outline/30' : isRace ? 'bg-primary-blue' : 'bg-charcoal-outline'}`} />
              
              {/* Session info */}
              <div className="flex-1">
                <div className={`text-sm font-medium ${!isActive ? 'text-gray-600' : isRace ? 'text-white' : 'text-gray-300'}`}>
                  {session.name}
                </div>
                <div className="text-[10px] text-gray-500">
                  {isActive ? `${session.duration} minutes` : 'Disabled'}
                </div>
              </div>
              
              {/* Duration bar */}
              {isActive && (
                <div className="w-16 h-2 bg-charcoal-outline/50 rounded-full overflow-hidden">
                  <div
                    className={`h-full rounded-full ${isRace ? 'bg-primary-blue' : 'bg-gray-600'}`}
                    style={{ width: `${(session.duration / Math.max(...activeSessions.map(s => s.duration))) * 100}%` }}
                  />
                </div>
              )}
            </div>
          );
        })}
      </div>

      {/* Legend */}
      <div className="flex items-center justify-center gap-4 pt-2 border-t border-charcoal-outline/30">
        <div className="flex items-center gap-1.5 text-[10px]">
          <div className="w-2 h-2 rounded bg-primary-blue" />
          <span className="text-gray-400">Active race</span>
        </div>
        <div className="flex items-center gap-1.5 text-[10px]">
          <div className="w-2 h-2 rounded bg-gray-600" />
          <span className="text-gray-400">Active session</span>
        </div>
        <div className="flex items-center gap-1.5 text-[10px]">
          <div className="w-2 h-2 rounded border border-dashed border-charcoal-outline/50 bg-transparent" />
          <span className="text-gray-500">Not included</span>
        </div>
      </div>

      {/* Summary */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3 text-[10px] text-gray-500">
          <span>{activeSessions.length} active sessions</span>
          <span>•</span>
          <span>{activeSessions.filter(s => s.type === 'race' || s.type === 'sprint').length} race{activeSessions.filter(s => s.type === 'race' || s.type === 'sprint').length > 1 ? 's' : ''}</span>
        </div>
        <div className="flex items-center gap-1.5 px-2 py-1 rounded-full bg-iron-gray/60">
          <Timer className="w-3 h-3 text-primary-blue" />
          <span className="text-xs font-semibold text-white">
            {Math.floor(totalDuration / 60)}h {totalDuration % 60}m
          </span>
        </div>
      </div>
    </div>
  );
}

/** Full Year Calendar View */
function YearCalendarPreview({
  weekdays,
  frequency,
  rounds,
  startDate,
  endDate,
}: {
  weekdays: Weekday[];
  frequency: RecurrenceStrategy;
  rounds: number;
  startDate?: string;
  endDate?: string;
}) {
  // 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,
  };

  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(() => {
    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
      const allPossibleDays: Date[] = [];
      const currentDate = new Date(seasonStart);
      
      while (currentDate <= seasonEnd) {
        const dayOfWeek = currentDate.getDay();
        if (selectedDayNumbers.has(dayOfWeek)) {
          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]!;
          dates.push(chosen);
        }
      } else {
        // Not enough days - use all available
        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) {
          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 = (date: Date) => {
    return date.getFullYear() === seasonStart.getFullYear() &&
           date.getMonth() === seasonStart.getMonth() &&
           date.getDate() === seasonStart.getDate();
  };
  
  const isSeasonEndDate = (date: Date) => {
    if (!seasonEnd) return false;
    return date.getFullYear() === seasonEnd.getFullYear() &&
           date.getMonth() === seasonEnd.getMonth() &&
           date.getDate() === seasonEnd.getDate();
  };

  // Create year view - DYNAMIC: shows months from first race to last race + some buffer
  const yearView = useMemo(() => {
    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();
      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);
        const days: DayInfo[] = [];
        
        for (let day = 1; day <= lastDay.getDate(); day++) {
          const date = new Date(targetYear, targetMonth, day);
          days.push({
            date,
            isRace: false,
            dayOfMonth: day,
            isStart: isSeasonStartDate(date),
            isEnd: isSeasonEndDate(date),
          });
        }
        
        view.push({
          month: months[targetMonth] ?? '—',
          monthIndex: targetMonth,
          year: targetYear,
          days
        });
      }
      
      return view;
    }
    
    // Get the range of months that contain races
    const firstRaceDate = raceDates[0]!;
    const lastRaceDate = raceDates[raceDates.length - 1]!;
    
    // Start from first race month, show 12 months total
    const startMonth = firstRaceDate.getMonth();
    const startYear = firstRaceDate.getFullYear();
    
    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);
      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;
        days.push({
          date,
          isRace,
          dayOfMonth: day,
          isStart: isSeasonStartDate(date),
          isEnd: isSeasonEndDate(date),
          ...(raceNumber !== undefined ? { raceNumber } : {}),
        });
      }
      
      view.push({
        month: months[targetMonth] ?? '—',
        monthIndex: targetMonth,
        year: targetYear,
        days
      });
    }
    
    return view;
  }, [raceDates, seasonStart, seasonEnd, months, 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 (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2 text-xs text-gray-400">
          <CalendarRange className="w-3.5 h-3.5 text-primary-blue" />
          <span className="font-medium text-white">Season Calendar</span>
        </div>
        <span className="text-[10px] text-gray-500">
          {raceDates.length} race{raceDates.length !== 1 ? 's' : ''} scheduled
        </span>
      </div>

      {/* Year grid - 3 columns x 4 rows */}
      <div className="grid grid-cols-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 (
            <div
              key={uniqueKey}
              className={`
                rounded-lg p-2 border transition-colors
                ${hasRaces
                  ? 'border-primary-blue/30 bg-primary-blue/5'
                  : 'border-charcoal-outline/30 bg-iron-gray/20'
                }
              `}
            >
              <div className="flex items-center justify-between mb-1">
                <span className={`text-[10px] font-medium ${hasRaces ? 'text-white' : 'text-gray-500'}`}>
                  {month} {year !== new Date().getFullYear() && <span className="text-gray-600">{year}</span>}
                </span>
                {raceCount > 0 && (
                  <span className="text-[9px] text-primary-blue font-medium">
                    {raceCount}
                  </span>
                )}
              </div>
              
              {/* Mini calendar grid */}
              <div className="grid grid-cols-7 gap-px">
                {/* 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) => (
                  <div key={`empty-${uniqueKey}-${i}`} className="w-2 h-2" />
                ))}
                
                {days.map(({ dayOfMonth, isRace, isStart, isEnd, raceNumber }) => (
                  <div
                    key={`${uniqueKey}-${dayOfMonth}`}
                    className={`
                      w-2 h-2 rounded-sm relative
                      ${isStart
                        ? 'bg-performance-green shadow-[0_0_6px_rgba(111,227,122,0.8)] ring-1 ring-performance-green'
                        : isEnd
                        ? 'bg-warning-amber shadow-[0_0_6px_rgba(255,197,86,0.8)] ring-1 ring-warning-amber'
                        : isRace
                        ? 'bg-primary-blue shadow-[0_0_4px_rgba(25,140,255,0.6)]'
                        : 'bg-charcoal-outline/30'
                      }
                    `}
                    title={
                      isStart ? `Season Start: ${month} ${dayOfMonth}, ${year}` :
                      isEnd ? `Season End: ${month} ${dayOfMonth}, ${year}` :
                      isRace ? `Round ${raceNumber}: ${month} ${dayOfMonth}, ${year}` :
                      undefined
                    }
                  />
                ))}
              </div>
            </div>
          );
        })}
      </div>

      {/* Season summary */}
      <div className="grid grid-cols-3 gap-2 pt-2 border-t border-charcoal-outline/30">
        <div className="text-center">
          <div className="text-lg font-bold text-white">{rounds}</div>
          <div className="text-[9px] text-gray-500">Rounds</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-white">
            {seasonDurationWeeks || '—'}
          </div>
          <div className="text-[9px] text-gray-500">Weeks</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-primary-blue">
            {firstRace && lastRace
              ? `${getMonthLabel(firstRace.getMonth())}–${getMonthLabel(
                  lastRace.getMonth(),
                )}`
              : '—'}
          </div>
          <div className="text-[9px] text-gray-500">Duration</div>
        </div>
      </div>

      {/* Legend */}
      <div className="flex items-center justify-center gap-3 flex-wrap text-[10px] text-gray-500">
        <div className="flex items-center gap-1">
          <div className="w-2 h-2 rounded-sm bg-performance-green ring-1 ring-performance-green" />
          <span>Start</span>
        </div>
        <div className="flex items-center gap-1">
          <div className="w-2 h-2 rounded-sm bg-primary-blue" />
          <span>Race</span>
        </div>
        {seasonEnd && (
          <div className="flex items-center gap-1">
            <div className="w-2 h-2 rounded-sm bg-warning-amber ring-1 ring-warning-amber" />
            <span>End</span>
          </div>
        )}
        <div className="flex items-center gap-1">
          <div className="w-2 h-2 rounded-sm bg-charcoal-outline/30" />
          <span>No race</span>
        </div>
      </div>
    </div>
  );
}

/** 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 (
    <div className="space-y-4">
      <div className="flex items-center gap-2 text-xs text-gray-400">
        <Trophy className="w-3.5 h-3.5 text-primary-blue" />
        <span className="font-medium text-white">Season Statistics</span>
      </div>

      {/* Visual rounds */}
      <div className="space-y-2">
        <div className="flex items-center gap-1 flex-wrap">
          {Array.from({ length: Math.min(rounds, 20) }).map((_, i) => (
            <div
              key={i}
              className={`
                w-5 h-5 rounded flex items-center justify-center text-[8px] font-bold
                transition-colors
                ${i === 0 
                  ? 'bg-performance-green text-white' 
                  : i === rounds - 1 
                  ? 'bg-primary-blue text-white'
                  : 'bg-iron-gray/60 border border-charcoal-outline text-gray-500 hover:border-primary-blue/50'
                }
              `}
            >
              {i + 1}
            </div>
          ))}
          {rounds > 20 && (
            <span className="text-[10px] text-gray-500 ml-1">+{rounds - 20}</span>
          )}
        </div>
        <div className="flex items-center gap-3 text-[10px] text-gray-500">
          <div className="flex items-center gap-1">
            <div className="w-2 h-2 rounded bg-performance-green" />
            <span>Season start</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-2 h-2 rounded bg-primary-blue" />
            <span>Finale</span>
          </div>
        </div>
      </div>

      {/* Stats grid */}
      <div className="grid grid-cols-2 gap-2">
        <div className="rounded-lg bg-iron-gray/30 border border-charcoal-outline/50 p-3">
          <div className="text-2xl font-bold text-white">{totalSessions}</div>
          <div className="text-[10px] text-gray-500">Total sessions</div>
        </div>
        <div className="rounded-lg bg-iron-gray/30 border border-charcoal-outline/50 p-3">
          <div className="text-2xl font-bold text-white">{Math.round(totalRaceMinutes / 60)}h</div>
          <div className="text-[10px] text-gray-500">Racing time</div>
        </div>
        <div className="rounded-lg bg-iron-gray/30 border border-charcoal-outline/50 p-3">
          <div className="text-2xl font-bold text-white">~{weeksNeeded}</div>
          <div className="text-[10px] text-gray-500">Weeks duration</div>
        </div>
        <div className="rounded-lg bg-iron-gray/30 border border-charcoal-outline/50 p-3">
          <div className="text-2xl font-bold text-white">{totalMinutesPerRound}</div>
          <div className="text-[10px] text-gray-500">min/race day</div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// 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 (
    <div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-iron-gray/60 to-iron-gray/30 border border-charcoal-outline">
      {isEditing ? (
        <input
          ref={inputRef}
          type="number"
          min={min}
          max={max}
          value={editValue}
          onChange={(e) => setEditValue(e.target.value)}
          onBlur={handleSubmit}
          onKeyDown={handleKeyDown}
          className="w-20 text-4xl font-bold text-center text-white bg-transparent border-b-2 border-primary-blue outline-none"
        />
      ) : (
        <button
          type="button"
          onClick={() => {
            setEditValue(value.toString());
            setIsEditing(true);
          }}
          className="group flex items-center gap-2 text-4xl font-bold text-white hover:text-primary-blue transition-colors"
        >
          {value}
          <Pencil className="w-4 h-4 opacity-0 group-hover:opacity-100 text-primary-blue transition-opacity" />
        </button>
      )}
      <div className="flex-1">
        <div className="text-sm font-medium text-gray-300">rounds</div>
        <div className="text-[10px] text-gray-500">Click to edit</div>
      </div>
      <div className="flex flex-col gap-1">
        <button
          type="button"
          onClick={() => onChange(Math.min(value + 1, max))}
          disabled={value >= max}
          className="p-1.5 rounded bg-iron-gray/60 border border-charcoal-outline hover:border-primary-blue disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
        >
          <ChevronUp className="w-4 h-4 text-gray-400" />
        </button>
        <button
          type="button"
          onClick={() => onChange(Math.max(value - 1, min))}
          disabled={value <= min}
          className="p-1.5 rounded bg-iron-gray/60 border border-charcoal-outline hover:border-primary-blue disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
        >
          <ChevronDown className="w-4 h-4 text-gray-400" />
        </button>
      </div>
    </div>
  );
}

// ============================================================================
// 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 (
    <div className="rounded-xl border border-charcoal-outline/50 bg-iron-gray/20 overflow-hidden transition-all duration-200">
      <button
        type="button"
        onClick={() => setIsOpen(!isOpen)}
        className="w-full flex items-center justify-between p-4 hover:bg-iron-gray/30 transition-colors"
      >
        <div className="flex items-center gap-3">
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary-blue/10 shrink-0">
            {icon}
          </div>
          <div className="text-left">
            <h3 className="text-sm font-semibold text-white">{title}</h3>
            {description && (
              <p className="text-xs text-gray-500 mt-0.5">{description}</p>
            )}
          </div>
        </div>
        <div className={`transform transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`}>
          <ChevronDown className="w-4 h-4 text-gray-400" />
        </div>
      </button>
      <div
        className={`transition-all duration-200 ease-in-out ${
          isOpen ? 'max-h-[2000px] opacity-100' : 'max-h-0 opacity-0 overflow-hidden'
        }`}
      >
        <div className="px-4 pb-4 pt-2 border-t border-charcoal-outline/30">
          {children}
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// 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 (
      <div className="space-y-4">
        <div className="text-lg font-semibold text-white">Schedule & timings</div>
        <div className="space-y-3 text-sm text-gray-300">
          <div>
            <span className="font-medium text-gray-200">Planned rounds:</span>{' '}
            <span>{timings.roundsPlanned ?? '—'}</span>
          </div>
        </div>
      </div>
    );
  }

  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 (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
      {/* LEFT COLUMN: Configuration */}
      <div className="space-y-4">
        {/* Session Durations - Collapsible */}
        <CollapsibleSection
          icon={<Timer className="w-4 h-4 text-primary-blue" />}
          title="Session Durations"
          description="Configure practice, qualifying, and race lengths"
          defaultOpen={false}
        >
          <div className="grid grid-cols-2 gap-3">
            <RangeField
              label="Practice"
              value={timings.practiceMinutes ?? 20}
              min={0}
              max={60}
              onChange={(v) => updateTimings({ practiceMinutes: v })}
              unitLabel="min"
              compact
            />
            <RangeField
              label="Qualifying"
              value={timings.qualifyingMinutes ?? 15}
              min={5}
              max={30}
              onChange={(v) => updateTimings({ qualifyingMinutes: v })}
              unitLabel="min"
              compact
              error={errors?.qualifyingMinutes}
            />
            {showSprint && (
              <RangeField
                label="Sprint Race"
                value={timings.sprintRaceMinutes ?? 20}
                min={10}
                max={45}
                onChange={(v) => updateTimings({ sprintRaceMinutes: v })}
                unitLabel="min"
                compact
              />
            )}
            <RangeField
              label={showSprint ? 'Feature Race' : 'Main Race'}
              value={timings.mainRaceMinutes ?? 40}
              min={15}
              max={180}
              onChange={(v) => updateTimings({ mainRaceMinutes: v })}
              unitLabel="min"
              compact
              error={errors?.mainRaceMinutes}
            />
          </div>
        </CollapsibleSection>

        {/* Season Length - Collapsible */}
        <CollapsibleSection
          icon={<Trophy className="w-4 h-4 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}
          />
          <p className="text-[10px] text-gray-500 mt-2">Each round is one complete race day. Click the number to edit directly.</p>
        </CollapsibleSection>

        {/* Race Schedule - Collapsible */}
        <CollapsibleSection
          icon={<CalendarDays className="w-4 h-4 text-primary-blue" />}
          title="Race Schedule"
          description="Weekly/bi-weekly and race days"
          defaultOpen={false}
        >
          {/* Frequency */}
          <div className="space-y-2 mb-4">
            <label className="text-xs text-gray-400">How often?</label>
            <div className="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 (
                  <button
                    key={opt.id}
                    type="button"
                    onClick={() =>
                      updateTimings({
                        recurrenceStrategy: opt.id as RecurrenceStrategy,
                        ...(opt.id === 'everyNWeeks'
                          ? { intervalWeeks: 2 }
                          : {}),
                      })
                    }
                    className={`
                      flex-1 px-3 py-2 rounded-lg border text-xs font-medium transition-all
                      ${isSelected
                        ? 'border-primary-blue bg-primary-blue/10 text-white'
                        : 'border-charcoal-outline bg-iron-gray/30 text-gray-400 hover:border-gray-500'
                      }
                    `}
                  >
                    {opt.label}
                  </button>
                );
              })}
            </div>
          </div>

          {/* Day selection */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <label className="text-xs text-gray-400">Which days?</label>
              {weekdays.length === 0 && (
                <span className="text-[10px] text-warning-amber">Select at least one</span>
              )}
            </div>

            <div className="flex gap-1">
              {allWeekdays.map(({ day, short }) => {
                const isSelected = weekdays.includes(day);
                return (
                  <button
                    key={day}
                    type="button"
                    onClick={() => handleWeekdayToggle(day)}
                    className={`
                      flex-1 py-2 rounded-lg border text-[10px] font-medium transition-all
                      ${isSelected
                        ? 'border-primary-blue bg-primary-blue text-white shadow-[0_0_8px_rgba(25,140,255,0.4)]'
                        : 'border-charcoal-outline bg-iron-gray/30 text-gray-500 hover:border-gray-500'
                      }
                    `}
                  >
                    {short}
                  </button>
                );
              })}
            </div>
          </div>
        </CollapsibleSection>

        {/* Season Duration - Collapsible */}
        <CollapsibleSection
          icon={<Calendar className="w-4 h-4 text-primary-blue" />}
          title="Season Duration"
          description="Start/end dates and time settings"
          defaultOpen={false}
        >
          <div className="space-y-4">
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <label className="text-[10px] text-gray-400 font-medium flex items-center gap-1">
                  <div className="w-2 h-2 rounded bg-performance-green" />
                  Season Start
                </label>
                <Input
                  type="date"
                  value={timings.seasonStartDate ?? ''}
                  onChange={(e) => updateTimings({ seasonStartDate: e.target.value })}
                  className="bg-iron-gray/30"
                />
              </div>
              <div className="space-y-1.5">
                <label className="text-[10px] text-gray-400 font-medium flex items-center gap-1">
                  <div className="w-2 h-2 rounded bg-warning-amber" />
                  Season End
                </label>
                <Input
                  type="date"
                  value={timings.seasonEndDate ?? ''}
                  onChange={(e) => updateTimings({ seasonEndDate: e.target.value })}
                  className="bg-iron-gray/30"
                />
              </div>
            </div>
            
            {timings.seasonStartDate && timings.seasonEndDate && (
              <div className="flex items-start gap-2 p-2 rounded-lg bg-primary-blue/5 border border-primary-blue/20">
                <Info className="w-3.5 h-3.5 text-primary-blue shrink-0 mt-0.5" />
                <p className="text-[10px] text-gray-400">
                  Races will be <span className="text-white font-medium">evenly distributed</span> between start and end dates on your selected race days.
                </p>
              </div>
            )}

            <div className="space-y-1.5">
              <label className="text-[10px] text-gray-400 font-medium">Race Start Time</label>
              <Input
                type="time"
                value={timings.raceStartTime ?? '20:00'}
                onChange={(e) => updateTimings({ raceStartTime: e.target.value })}
                className="bg-iron-gray/30"
              />
            </div>

            {/* Time Zone Selector */}
            <div className="space-y-1.5">
              <label className="text-[10px] text-gray-400 font-medium">Time Zone</label>
              <div className="grid grid-cols-2 gap-2">
                {TIME_ZONES.slice(0, 2).map((tz) => {
                  const isSelected = (timings.timezoneId ?? 'UTC') === tz.value;
                  const Icon = tz.icon;
                  return (
                    <button
                      key={tz.value}
                      type="button"
                      onClick={() => updateTimings({ timezoneId: tz.value })}
                      className={`
                        flex items-center gap-2 px-3 py-2.5 rounded-lg border text-left transition-all
                        ${isSelected
                          ? tz.value === 'track'
                            ? 'border-performance-green bg-performance-green/10 shadow-[0_0_12px_rgba(111,227,122,0.2)]'
                            : 'border-primary-blue bg-primary-blue/10 shadow-[0_0_12px_rgba(25,140,255,0.2)]'
                          : 'border-charcoal-outline bg-iron-gray/30 hover:border-gray-500'
                        }
                      `}
                    >
                      <Icon className={`w-4 h-4 ${isSelected ? (tz.value === 'track' ? 'text-performance-green' : 'text-primary-blue') : 'text-gray-400'}`} />
                      <div className="flex-1">
                        <div className={`text-xs font-medium ${isSelected ? 'text-white' : 'text-gray-300'}`}>
                          {tz.label}
                        </div>
                        {tz.value === 'track' && (
                          <div className="text-[9px] text-gray-500">Adjusts per track</div>
                        )}
                      </div>
                    </button>
                  );
                })}
              </div>
              
              {/* More time zones - expandable */}
              <button
                type="button"
                onClick={() => setShowAdvanced(!showAdvanced)}
                className="flex items-center gap-1.5 text-[10px] text-gray-400 hover:text-white transition-colors"
              >
                {showAdvanced ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
                {showAdvanced ? 'Hide' : 'Show'} more time zones
              </button>
              
              {showAdvanced && (
                <div className="grid grid-cols-2 gap-2 mt-2">
                  {TIME_ZONES.slice(2).map((tz) => {
                    const isSelected = (timings.timezoneId ?? 'UTC') === tz.value;
                    const Icon = tz.icon;
                    return (
                      <button
                        key={tz.value}
                        type="button"
                        onClick={() => updateTimings({ timezoneId: tz.value })}
                        className={`
                          flex items-center gap-2 px-3 py-2 rounded-lg border text-left transition-all text-xs
                          ${isSelected
                            ? 'border-primary-blue bg-primary-blue/10'
                            : 'border-charcoal-outline bg-iron-gray/30 hover:border-gray-500'
                          }
                        `}
                      >
                        <Icon className={`w-3.5 h-3.5 ${isSelected ? 'text-primary-blue' : 'text-gray-500'}`} />
                        <span className={isSelected ? 'text-white' : 'text-gray-400'}>{tz.label}</span>
                      </button>
                    );
                  })}
                </div>
              )}
            </div>
            
            <div className="flex items-start gap-2 p-2 rounded-lg bg-performance-green/5 border border-performance-green/20">
              <Info className="w-3.5 h-3.5 text-performance-green shrink-0 mt-0.5" />
              <p className="text-[10px] 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.'
                }
              </p>
            </div>
          </div>
        </CollapsibleSection>
      </div>

      {/* RIGHT COLUMN: Live Preview */}
      <div className="space-y-4">
        <div className="sticky top-4">
          <div className="rounded-xl border border-charcoal-outline bg-gradient-to-br from-iron-gray/80 to-deep-graphite overflow-hidden">
            {/* Preview header with tabs */}
            <div className="flex items-center justify-between p-3 border-b border-charcoal-outline/50 bg-deep-graphite/50">
              <div className="flex items-center gap-2">
                <Eye className="w-4 h-4 text-primary-blue" />
                <span className="text-xs font-semibold text-white">Preview</span>
              </div>
              <div className="flex gap-1 p-0.5 rounded-lg 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) => (
                  <button
                    key={tab.id}
                    type="button"
                    onClick={() => setPreviewTab(tab.id as typeof previewTab)}
                    className={`
                      flex items-center gap-1 px-2 py-1 text-[10px] font-medium rounded transition-colors
                      ${previewTab === tab.id
                        ? 'bg-primary-blue text-white'
                        : 'text-gray-400 hover:text-white'
                      }
                    `}
                  >
                    <tab.icon className="w-3 h-3" />
                    <span className="hidden sm:inline">{tab.label}</span>
                  </button>
                ))}
              </div>
            </div>

            {/* Preview content */}
            <div className="p-4 min-h-[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}
                  />
                );
              })()}
            </div>
          </div>

          {/* Helper tip */}
          <div className="mt-3 flex items-start gap-2 p-3 rounded-lg bg-primary-blue/5 border border-primary-blue/20">
            <Info className="w-4 h-4 text-primary-blue shrink-0 mt-0.5" />
            <p className="text-[11px] text-gray-400 leading-relaxed">
              Preview updates live as you configure. Check <span className="text-white font-medium">Race Day</span> for session timing, <span className="text-white font-medium">Calendar</span> for the full year view, and <span className="text-white font-medium">Stats</span> for season totals.
            </p>
          </div>
        </div>
      </div>
    </div>
  );
}