'use client';

import { useMemo } from 'react';
import { format, startOfWeek, addDays, parseISO } from 'date-fns';
import { cs } from 'date-fns/locale';
import { LocalData, SubstitutionData, ChangeEntry, Hour } from '@/lib/types';
import { Card } from '@/components/ui/card';
import { capitalizeFirstLetter } from '@/lib/utils';

interface ScheduleViewerProps {
  localData: LocalData;
  substitutionData: SubstitutionData | null;
  hideSubstitutions?: boolean;
}

function getChangesForClass(changes: Record<string, (ChangeEntry | null)[]> | undefined, className: string): (ChangeEntry | null)[] {
  if (!changes) return [];
  
  if (changes[className]) return changes[className];
  
  const key = Object.keys(changes).find(k => k.toLowerCase() === className.toLowerCase());
  if (key) return changes[key];
  
  return [];
}

export default function ScheduleViewer({ localData, substitutionData, hideSubstitutions = false }: ScheduleViewerProps) {
  const referenceDate = useMemo(() => {
    if (substitutionData?.schedule) {
      const dates = Object.keys(substitutionData.schedule).sort();
      if (dates.length > 0) {
        return parseISO(dates[0]);
      }
    }
    return new Date();
  }, [substitutionData]);

  const mondayDate = useMemo(() => {
    return startOfWeek(referenceDate, { weekStartsOn: 1 });
  }, [referenceDate]);

  const weekDays = useMemo(() => {
    return Array.from({ length: 5 }, (_, i) => addDays(mondayDate, i));
  }, [mondayDate]);

  const maxHours = useMemo(() => {
    let max = 0;
    localData.timetable.forEach(day => {
      if (day.length > max) max = day.length;
    });
    return max;
  }, [localData]);

  const currentWeekMaxHours = useMemo(() => {
    let max = maxHours;
    if (!hideSubstitutions && substitutionData?.schedule) {
      weekDays.forEach(date => {
        const dateStr = format(date, 'yyyy-MM-dd');
        const dayData = substitutionData.schedule[dateStr];
        if (dayData && dayData.changes) {
           const changes = getChangesForClass(dayData.changes, localData.class);
           if (changes.length > max) max = changes.length;
        }
      });
    }
    return max;
  }, [maxHours, substitutionData, weekDays, localData.class, hideSubstitutions]);

  const hours = Array.from({ length: currentWeekMaxHours }, (_, i) => i + 1);

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
         <div className="text-sm text-muted-foreground">
           Zobrazen týden od {format(mondayDate, 'd. M.', { locale: cs })} do {format(weekDays[4], 'd. M. yyyy', { locale: cs })}
        </div>
      </div>

      <Card className="overflow-hidden border p-0">
        <div className="overflow-x-auto">
          <table className="w-full text-sm text-left border-collapse">
            <thead>
              <tr>
                <th className="p-3 font-semibold border-b border-r min-w-[100px] text-center">
                  Den
                </th>
                {hours.map(h => (
                  <th key={h} className="p-3 font-semibold border-b border-r min-w-[120px] text-center">
                    {h}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {weekDays.map((date, dayIndex) => {
                const dateStr = format(date, 'yyyy-MM-dd');
                const dayName = format(date, 'EEEE', { locale: cs });
                
                const staticDay = localData.timetable[dayIndex] || [];
                
                const dynamicDay = substitutionData?.schedule?.[dateStr];
                const changes = getChangesForClass(dynamicDay?.changes, localData.class);

                const has3 = hours.some((_, hourIndex) => staticDay[hourIndex].length == 3);

                return (
                  <tr key={dateStr} className="border-b last:border-0 group hover:bg-muted/5" style={{height: has3 ? "120px" : "80px"}}>
                    <td className="p-3 font-medium border-r text-center">
                      <div className="capitalize">{dayName}</div>
                      <div className="text-xs text-muted-foreground">{format(date, 'd. M.')}</div>
                    </td>
                    {hours.map((_, hourIndex) => {
                      const change = changes[hourIndex];
                      const staticLessons = staticDay[hourIndex] || [];
                      
                      return (
                        <td key={hourIndex} className="border-r min-w-[120px] h-full align-top relative p-0">
                          <CellContent 
                            staticLessons={staticLessons} 
                            change={hideSubstitutions ? null : change} 
                          />
                        </td>
                      );
                    })}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </Card>
    </div>
  );
}

function CellContent({ staticLessons, change }: { staticLessons: Hour[], change: ChangeEntry | null | undefined }) {
  if (change) {
    return (
      <div 
        className="w-full h-full p-2 text-xs flex items-center justify-center text-center font-medium shadow-sm"
        style={{
          backgroundColor: change.backgroundColor || '#f0f0f0',
          color: change.foregroundColor ? "#" + change.foregroundColor.substring(3, 6) : '#000',
        }}
      >
        {change.text}
      </div>
    );
  }

  if (!staticLessons || staticLessons.length === 0) {
    return null;
  }

  if (staticLessons.length > 1) {
    return (
      <div className="flex flex-col min-h-[80px] h-full">
        {staticLessons.map((lesson, idx) => (
          <div key={idx} className="flex-1 flex flex-col justify-between p-1 text-[10px] border-b min-h-[40px]">
             <div className='flex justify-between'>
               <div className="font-bold truncate">{lesson.subject}</div>
               <span className="truncate opacity-70">{capitalizeFirstLetter(lesson.teacher.code)}</span>
             </div>
             <div className="flex justify-between">
               <span className="truncate max-w-[40px]">{lesson.room}</span>
               <span className="truncate opacity-70">{lesson.group}</span>
             </div>
          </div>
        ))}
      </div>
    );
  }

  const lesson = staticLessons[0];
  return (
    <div className="w-full min-h-[80px] h-full p-2 border-b flex flex-col justify-between text-xs hover:shadow-md transition-shadow">
      <div className="font-bold text-lg text-primary">{lesson.subject}</div>
      <div className="flex justify-between items-end mt-1">
        <div className="font-mono font-medium">{lesson.room}</div>
        <div className="text-[10px] opacity-80" title={lesson.teacher.name}>{capitalizeFirstLetter(lesson.teacher.code)}</div>
      </div>
    </div>
  );
}
