import { TimeSlot, Participant } from '@/types/calendar';
import { cn } from '@/lib/utils';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { Button } from '@/components/ui/button';
import { useState, useMemo, useRef, useEffect } from 'react';
import { Check, X, Loader2, ChevronLeft, ChevronRight, ChevronsRight, Clock, Calendar as CalendarIcon, Sun, Moon, Users } from 'lucide-react';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';

const DEFAULT_TIMEZONE = 'America/Toronto';
const dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const WORKING_HOUR_START = 8; // 8 AM
const WORKING_HOUR_END = 18; // 6 PM
const ALL_HOURS = Array.from({ length: 24 }, (_, i) => i);
const WORKING_HOURS = Array.from({ length: WORKING_HOUR_END - WORKING_HOUR_START + 1 }, (_, i) => i + WORKING_HOUR_START);

// Helper to check if a slot is in the past or too close (2h buffer)
const isSlotTooSoon = (slotDate: number) => {
  const now = Date.now();
  const twoHoursFromNow = now + 2 * 60 * 60 * 1000;
  return slotDate < twoHoursFromNow;
};

// Reuse previous timezone helpers or simplify
const getWeekDates = (timezone: string, weekOffset: number = 0): Date[] => {
  const now = new Date();
  const formatter = new Intl.DateTimeFormat('en-CA', {
    timeZone: timezone,
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  });

  const todayStr = formatter.format(now);
  const [year, month, day] = todayStr.split('-').map(Number);

  const todayDate = new Date(year, month - 1, day);
  const dayOfWeek = todayDate.getDay();
  // If Sunday (0), go back 6 days to Monday. If Mon (1), go back 0. If Sat (6), go back 5.
  // Actually standard logic: Mon=1...Sun=7. 
  // Let's assume standard ISO week start (Mon)
  const daysToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
  const mondayDate = new Date(year, month - 1, day + daysToMonday + weekOffset * 7);

  return Array.from({ length: 5 }, (_, i) => {
    const d = new Date(mondayDate);
    d.setDate(mondayDate.getDate() + i);
    return d;
  });
};

const formatTimezoneDisplay = (timezone: string): string => {
  try {
    const parts = timezone.split('/');
    const city = parts[parts.length - 1].replace(/_/g, ' ');
    return city;
  } catch {
    return timezone;
  }
};

interface AvailabilityHeatmapV2Props {
  slots: TimeSlot[];
  selectedParticipants: Participant[];
  onSlotSelect: (slot: TimeSlot) => void;
  showPartialAvailability?: boolean;
  isLoading?: boolean;
  weekOffset?: number;
  onWeekOffsetChange?: (offset: number) => void;
  displayTimezone?: string;
  showSecondaryTimezone?: boolean;
  secondaryTimezone?: string;
}

export const AvailabilityHeatmapV2 = ({
  slots,
  selectedParticipants,
  onSlotSelect,
  showPartialAvailability = false,
  isLoading = false,
  weekOffset = 0,
  onWeekOffsetChange,
  displayTimezone = DEFAULT_TIMEZONE,
  showSecondaryTimezone = false,
  secondaryTimezone = DEFAULT_TIMEZONE,
}: AvailabilityHeatmapV2Props) => {
  const [showFullDay, setShowFullDay] = useState(false);
  const activeHours = showFullDay ? ALL_HOURS : WORKING_HOURS;

  const weekDates = useMemo(() => getWeekDates(displayTimezone, weekOffset), [displayTimezone, weekOffset]);

  // Pre-compute slots lookup map for O(1) access
  // Key: YYYY-MM-DD:Hour
  const slotsMap = useMemo(() => {
    const map = new Map<string, TimeSlot>();
    slots.forEach(slot => {
      // Assuming slot.start_time is ISO string. 
      // We need to match it to our grid's local time logic.
      // This part is "flaky" in the original. 
      // The slot comes with a specific absolute time.
      // We want to place it in the intersection of "Day (in DisplayTZ)" and "Hour (in DisplayTZ)".

      const d = new Date(slot.start_time);
      // Format to DisplayTZ to find coordinate
      const formatter = new Intl.DateTimeFormat('en-CA', {
        timeZone: displayTimezone,
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: 'numeric',
        hour12: false
      });
      // "2023-10-25, 14"
      const parts = formatter.formatToParts(d);
      const year = parts.find(p => p.type === 'year')?.value;
      const month = parts.find(p => p.type === 'month')?.value;
      const day = parts.find(p => p.type === 'day')?.value;
      const hour = parts.find(p => p.type === 'hour')?.value;

      if (year && month && day && hour) {
        // Hour in 24h format might be "24" in some locales? No `hour12: false` gives 0-23 usually.
        // But Intl sometimes returns "24"? No, 0-23.
        let h = parseInt(hour, 10);
        if (h === 24) h = 0; // Just in case

        const key = `${year}-${month}-${day}:${h}`;
        map.set(key, slot);
      }
    });
    return map;
  }, [slots, displayTimezone]);

  const formatDateKey = (date: Date) => {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
  };

  const formatDisplayDate = (date: Date) => {
    return date.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
  };

  const getSlotForCell = (date: Date, hour: number) => {
    const key = `${formatDateKey(date)}:${hour}`;
    return slotsMap.get(key);
  };

  const formatHour = (hour: number) => {
    return new Date(0, 0, 0, hour).toLocaleTimeString('en-US', {
      hour: 'numeric',
      hour12: true,
    });
  };

  if (selectedParticipants.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center p-12 border-2 border-dashed border-border/50 rounded-xl bg-muted/20 animate-fade-in">
        <UsersPlaceholder />
        <h3 className="text-xl font-semibold mt-4">No participants selected</h3>
        <p className="text-muted-foreground text-center max-w-sm mt-2">
          Select team members from the list above to compare calendars and find the perfect meeting time.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-4 animate-in fade-in slide-in-from-bottom-4 duration-500">
      {/* Controls Bar */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 bg-card p-4 rounded-xl border border-border shadow-sm">
        <div className="flex items-center gap-4">
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="icon"
              className="h-9 w-9"
              onClick={() => onWeekOffsetChange?.(weekOffset - 1)}
              disabled={!onWeekOffsetChange || weekOffset <= 0}
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <div className="flex flex-col items-center min-w-[140px]">
              <span className="text-sm font-semibold">
                {weekDates[0]?.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
                {' - '}
                {weekDates[4]?.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
              </span>
              <span className="text-xs text-muted-foreground">
                {weekOffset === 0 ? "This Week" : weekOffset === 1 ? "Next Week" : `${weekOffset} weeks out`}
              </span>
            </div>
            <Button
              variant="outline"
              size="icon"
              className="h-9 w-9"
              onClick={() => onWeekOffsetChange?.(weekOffset + 1)}
              disabled={!onWeekOffsetChange}
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>

          <div className="h-8 w-px bg-border hidden sm:block" />

          <div className="flex items-center gap-2 text-sm text-muted-foreground bg-muted/50 px-3 py-1.5 rounded-md">
            <Clock className="w-4 h-4" />
            {formatTimezoneDisplay(displayTimezone)}
          </div>
        </div>

        <div className="flex items-center gap-2">
          <Button
            variant={showFullDay ? "outline" : "secondary"}
            size="sm"
            onClick={() => setShowFullDay(!showFullDay)}
            className="text-xs"
          >
            {showFullDay ? (
              <>
                <Sun className="w-3.5 h-3.5 mr-2" />
                Show Work Hours
              </>
            ) : (
              <>
                <Moon className="w-3.5 h-3.5 mr-2" />
                Show Full Day
              </>
            )}
          </Button>
        </div>
      </div>

      {/* Main Grid Card */}
      <div className="bg-card w-full overflow-hidden rounded-xl border border-border shadow-md">
        {isLoading && (
          <div className="absolute inset-0 bg-background/50 backdrop-blur-[1px] z-50 flex items-center justify-center">
            <Loader2 className="w-10 h-10 animate-spin text-primary" />
          </div>
        )}

        <div className="overflow-auto max-h-[600px] w-full relative">
          <div className="min-w-[700px]">
            {/* Grid Header */}
            <div className="grid grid-cols-[80px_repeat(5,1fr)] sticky top-0 z-30 bg-card border-b border-border shadow-sm">
              <div className="sticky left-0 z-40 bg-card text-xs font-semibold text-muted-foreground self-center p-3 text-right border-r border-border/50">
                TIME
              </div>
              {weekDates.map(date => {
                const isToday = new Date().toDateString() === date.toDateString();
                return (
                  <div key={date.toISOString()} className={cn(
                    "text-center p-3 transition-colors border-r border-border/30 last:border-0",
                    isToday ? "bg-primary/5 text-primary font-bold" : "text-foreground"
                  )}>
                    <div className="text-sm">{date.toLocaleDateString('en-US', { weekday: 'short' })}</div>
                    <div className={cn("text-2xl", isToday ? "font-bold" : "font-light")}>
                      {date.getDate()}
                    </div>
                  </div>
                );
              })}
            </div>

            {/* Grid Body */}
            <div className="relative">
              {activeHours.map((hour) => {
                const isNight = hour < 8 || hour >= 18;
                return (
                  <div
                    key={hour}
                    className={cn(
                      "grid grid-cols-[80px_repeat(5,1fr)] group items-stretch transition-colors border-b border-border/30 last:border-0",
                      isNight ? "bg-muted/30" : "bg-card",
                      "hover:bg-muted/10"
                    )}
                  >
                    {/* Time Label - Sticky Left */}
                    <div className={cn(
                      "text-xs text-muted-foreground font-medium text-right pr-4 py-3 flex items-center justify-end gap-1.5",
                      "sticky left-0 z-20 border-r border-border/50",
                      isNight ? "bg-muted/30 backdrop-blur-md" : "bg-card"
                    )}>
                      {isNight ? (
                        <Moon className="w-3 h-3 text-slate-400/50" />
                      ) : (
                        <Sun className="w-3 h-3 text-amber-500/50" />
                      )}
                      {formatHour(hour)}
                    </div>

                    {/* Days */}
                    {weekDates.map(date => {
                      const slot = getSlotForCell(date, hour);
                      const tooSoon = slot ? isSlotTooSoon(new Date(slot.start_time).getTime()) : true;

                      // Availability logic
                      const availability = slot?.availability || 'none';
                      const isNone = availability === 'none';
                      const isPartial = availability === 'partial' && showPartialAvailability;
                      const isFull = availability === 'full';
                      const isPartialHidden = availability === 'partial' && !showPartialAvailability;

                      // Styling
                      let bgClass = ""; // Default transparent
                      if (!slot) bgClass = "bg-muted/10 pattern-diagonal-lines opacity-50";
                      else if (isFull) bgClass = "bg-emerald-500/90 hover:bg-emerald-600 shadow-sm";
                      else if (isPartial) bgClass = "bg-amber-400/80 hover:bg-amber-500 shadow-sm";
                      else if (isNone || isPartialHidden) bgClass = "bg-transparent hover:bg-muted/20";

                      if (tooSoon && slot) bgClass = cn(bgClass, "opacity-30 cursor-not-allowed pattern-diagonal-lines");

                      return (
                        <div key={date.toISOString()} className="p-1 h-[52px] border-r border-border/30 last:border-0">
                          {slot ? (
                            <Popover>
                              <PopoverTrigger asChild disabled={tooSoon}>
                                <div className={cn(
                                  "w-full h-full rounded-md transition-all duration-200 cursor-pointer flex items-center justify-center group/cell relative overflow-hidden",
                                  bgClass,
                                  !tooSoon && (isFull || isPartial) ? "scale-[0.98] hover:scale-100 hover:ring-2 ring-primary/20" : ""
                                )}>
                                  {/* Mini Indicators for color-blind accessibility or density */}
                                  {isFull && <Check className="w-4 h-4 text-white opacity-0 group-hover/cell:opacity-100 transition-opacity" />}
                                </div>
                              </PopoverTrigger>
                              <PopoverContent className="w-72 p-0 rounded-xl overflow-hidden shadow-xl border-border" side="right" align="start">
                                <div className="p-4 bg-muted/30 border-b border-border/50">
                                  <h4 className="font-semibold text-base flex items-center gap-2">
                                    <CalendarIcon className="w-4 h-4 text-muted-foreground" />
                                    {formatDisplayDate(date)}
                                  </h4>
                                  <div className="text-sm text-muted-foreground mt-1 flex items-center gap-2">
                                    <Clock className="w-4 h-4" />
                                    {formatHour(hour)} - {formatHour(hour + 1)}
                                  </div>
                                </div>

                                <div className="p-4 space-y-3 max-h-[300px] overflow-y-auto">
                                  <div className="space-y-2">
                                    {selectedParticipants.map(participant => {
                                      const isAvailable = slot.availableParticipants.includes(participant.name);
                                      return (
                                        <div key={participant.id} className="flex items-center justify-between text-sm p-2 rounded-lg hover:bg-muted/50 transition-colors">
                                          <div className="flex items-center gap-3">
                                            <div className={cn(
                                              "w-2 h-2 rounded-full",
                                              isAvailable ? "bg-emerald-500" : "bg-destructive"
                                            )} />
                                            <span className={cn(!isAvailable && "text-muted-foreground")}>
                                              {participant.name}
                                            </span>
                                          </div>
                                          {isAvailable ? (
                                            <Check className="w-4 h-4 text-emerald-500" />
                                          ) : (
                                            <span className="text-xs text-muted-foreground">Busy</span>
                                          )}
                                        </div>
                                      );
                                    })}
                                  </div>

                                  {(!isNone && !tooSoon) && (
                                    <Button
                                      className="w-full mt-4 bg-emerald-600 hover:bg-emerald-700 text-white"
                                      onClick={() => onSlotSelect(slot)}
                                    >
                                      Schedule Meeting
                                    </Button>
                                  )}
                                </div>
                              </PopoverContent>
                            </Popover>
                          ) : (
                            // Placeholder for missing slots
                            <div className="w-full h-full rounded-md bg-muted/5 border border-dashed border-border/30"></div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        {/* Legend */}
        <div className="flex flex-wrap items-center justify-center bg-muted/20 border-t p-3 gap-6 text-sm">
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-emerald-500 shadow-sm"></div>
            <span className="font-medium text-foreground">All Available</span>
          </div>
          {showPartialAvailability && (
            <div className="flex items-center gap-2">
              <div className="w-3 h-3 rounded-full bg-amber-400 shadow-sm"></div>
              <span className="font-medium text-foreground">Partial Match</span>
            </div>
          )}
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded border border-slate-300 bg-slate-100 dark:bg-slate-800 dark:border-slate-700"></div>
            <span className="text-muted-foreground">Busy / No Match</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded bg-muted/30 pattern-diagonal-lines ring-1 ring-border/50"></div>
            <span className="text-muted-foreground">Past / Too Soon</span>
          </div>
        </div>
      </div>
    </div>
  );
};

function UsersPlaceholder() {
  return (
    <div className="relative w-16 h-16 mb-2">
      <div className="absolute top-0 left-0 w-10 h-10 rounded-full bg-muted border-2 border-background flex items-center justify-center">
        <Users className="w-5 h-5 text-muted-foreground" />
      </div>
      <div className="absolute bottom-0 right-0 w-10 h-10 rounded-full bg-muted border-2 border-background flex items-center justify-center">
        <Users className="w-5 h-5 text-muted-foreground" />
      </div>
    </div>
  );
}

// Importing Users icon since it was missing in imports
