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 { Check, X, Loader2 } from 'lucide-react';

const dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const hours = [9, 10, 11, 12, 13, 14, 15, 16, 17];

// Get the dates for Mon-Fri of the current week
const getWeekDates = () => {
  const now = new Date();
  const monday = new Date(now);
  monday.setDate(now.getDate() - now.getDay() + 1);
  monday.setHours(0, 0, 0, 0);

  return dayNames.map((_, i) => {
    const date = new Date(monday);
    date.setDate(monday.getDate() + i);
    return date.toISOString().split('T')[0]; // "YYYY-MM-DD"
  });
};

interface AvailabilityHeatmapProps {
  slots: TimeSlot[];
  selectedParticipants: Participant[];
  onSlotSelect: (slot: TimeSlot) => void;
  showPartialAvailability?: boolean;
  isLoading?: boolean;
}

export const AvailabilityHeatmap = ({
  slots,
  selectedParticipants,
  onSlotSelect,
  showPartialAvailability = false,
  isLoading = false,
}: AvailabilityHeatmapProps) => {
  const weekDates = getWeekDates();

  const getSlot = (dateStr: string, hour: number) => {
    return slots.find((s) => s.day === dateStr && s.hour === hour);
  };

  const getEffectiveAvailability = (slot: TimeSlot) => {
    if (slot.availability === 'partial' && !showPartialAvailability) {
      return 'none';
    }
    return slot.availability;
  };

  const formatHour = (hour: number) => {
    return `${hour.toString().padStart(2, '0')}:00`;
  };

  const isSlotTooSoon = (dateStr: string, hour: number) => {
    const slotTime = new Date(`${dateStr}T${formatHour(hour)}:00Z`);
    const now = new Date();
    const twoHoursFromNow = new Date(now.getTime() + 2 * 60 * 60 * 1000);
    return slotTime < twoHoursFromNow;
  };

  const getWeekDateRange = () => {
    const now = new Date();
    const monday = new Date(now);
    monday.setDate(now.getDate() - now.getDay() + 1);
    const friday = new Date(monday);
    friday.setDate(monday.getDate() + 4);

    const format = (d: Date) => d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    return `${format(monday)} – ${format(friday)}`;
  };

  if (selectedParticipants.length === 0) {
    return (
      <div className="bg-card rounded-xl shadow-card p-8 text-center animate-fade-in">
        <div className="text-muted-foreground">
          <p className="text-lg font-medium mb-2">Select participants to view availability</p>
          <p className="text-sm">Add people from the search above to see their common free times</p>
        </div>
      </div>
    );
  }

  if (isLoading) {
    return (
      <div className="bg-card rounded-xl shadow-card p-8 text-center animate-fade-in">
        <Loader2 className="w-8 h-8 mx-auto mb-4 animate-spin text-primary" />
        <p className="text-muted-foreground">Loading availability...</p>
      </div>
    );
  }

  return (
    <div className="bg-card rounded-xl shadow-card p-6 animate-slide-up">
      <div className="mb-6">
        <h3 className="text-lg font-semibold text-foreground">
          Common Availability — Week of {getWeekDateRange()}
        </h3>
        <p className="text-sm text-muted-foreground mt-1">
          {selectedParticipants.length} participant{selectedParticipants.length > 1 ? 's' : ''}: {selectedParticipants.map(p => p.name.split(' ')[0]).join(', ')}
        </p>
      </div>

      <div className="overflow-x-auto">
        <div className="min-w-[600px]">
          <div className="grid grid-cols-[60px_repeat(5,1fr)] gap-1 mb-2">
            <div></div>
            {dayNames.map((dayName) => (
              <div
                key={dayName}
                className="text-center text-sm font-medium text-muted-foreground py-2"
              >
                {dayName}
              </div>
            ))}
          </div>

          <div className="space-y-1">
            {hours.map((hour) => (
              <div key={hour} className="grid grid-cols-[60px_repeat(5,1fr)] gap-1">
                <div className="text-xs text-muted-foreground flex items-center justify-end pr-3">
                  {formatHour(hour)}
                </div>
                {weekDates.map((dateStr, dayIndex) => {
                  const slot = getSlot(dateStr, hour);
                  const dayName = dayNames[dayIndex];
                  const tooSoon = isSlotTooSoon(dateStr, hour);
                  if (!slot) return <div key={`${dateStr}-${hour}`} className="h-12 bg-muted rounded" />;

                  const effectiveAvailability = getEffectiveAvailability(slot);

                  return (
                    <Popover key={`${dateStr}-${hour}`}>
                      <PopoverTrigger asChild>
                        <button
                          className={cn(
                            "h-12 rounded-md transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
                            tooSoon && "opacity-40 cursor-not-allowed",
                            !tooSoon && "hover:scale-105 hover:shadow-md",
                            effectiveAvailability === 'full' && "bg-availability-full hover:bg-availability-full/90",
                            effectiveAvailability === 'partial' && "bg-availability-partial hover:bg-availability-partial/90",
                            effectiveAvailability === 'none' && "bg-availability-none hover:bg-availability-none/90"
                          )}
                        />
                      </PopoverTrigger>
                      <PopoverContent className="w-64 p-4 animate-scale-in" align="center">
                        <div className="space-y-3">
                          <div className="font-semibold text-foreground">
                            {dayName} {formatHour(hour)}–{formatHour(hour + 1)}
                          </div>
                          {tooSoon && (
                            <div className="text-sm text-muted-foreground italic">
                              This time slot has passed or is too soon to schedule
                            </div>
                          )}
                          <div className="space-y-2">
                            {selectedParticipants.map((participant) => {
                              const isAvailable = slot.availableParticipants.includes(participant.name);
                              return (
                                <div
                                  key={participant.id}
                                  className="flex items-center gap-2 text-sm"
                                >
                                  {isAvailable ? (
                                    <Check className="w-4 h-4 text-availability-full" />
                                  ) : (
                                    <X className="w-4 h-4 text-destructive" />
                                  )}
                                  <span className={cn(
                                    isAvailable ? "text-foreground" : "text-muted-foreground"
                                  )}>
                                    {participant.name.split(' ')[0]} {isAvailable ? 'free' : 'busy'}
                                  </span>
                                </div>
                              );
                            })}
                          </div>
                          {effectiveAvailability !== 'none' && !tooSoon && (
                            <Button
                              variant="schedule"
                              className="w-full mt-2"
                              onClick={() => onSlotSelect(slot)}
                            >
                              Schedule
                            </Button>
                          )}
                        </div>
                      </PopoverContent>
                    </Popover>
                  );
                })}
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="flex items-center justify-center gap-6 mt-6 pt-4 border-t border-border">
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded bg-availability-full"></div>
          <span className="text-xs text-muted-foreground">All free</span>
        </div>
        {showPartialAvailability && (
          <div className="flex items-center gap-2">
            <div className="w-4 h-4 rounded bg-availability-partial"></div>
            <span className="text-xs text-muted-foreground">Partial</span>
          </div>
        )}
        <div className="flex items-center gap-2">
          <div className="w-4 h-4 rounded bg-availability-none"></div>
          <span className="text-xs text-muted-foreground">No overlap</span>
        </div>
      </div>
    </div>
  );
};
