"use client";

import { useState, useRef, useEffect } from "react";
import FullCalendar from "@fullcalendar/react";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import frLocale from "@fullcalendar/core/locales/fr";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { 
  Loader2, 
  Plus, 
  Calendar as CalendarIcon, 
  Check, 
  X, 
  User, 
  Clock, 
  BarChart2, 
  Settings, 
  ChevronRight,
  ChevronLeft,
  Bell,
  Users,
  MapPin,
  Tag,
  ChevronDown,
  ChevronUp
} from "lucide-react";
import { Calendar, Event } from "@prisma/client";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";

// Predefined professional color palette
const colorPalette = [
  "#4f46e5", // Indigo
  "#0891b2", // Cyan
  "#0e7490", // Teal
  "#16a34a", // Green
  "#65a30d", // Lime
  "#ca8a04", // Amber
  "#d97706", // Orange
  "#dc2626", // Red
  "#e11d48", // Rose
  "#9333ea", // Purple
  "#7c3aed", // Violet
  "#2563eb", // Blue
];

interface CalendarClientProps {
  initialCalendars: (Calendar & { events: Event[] })[];
  userId: string;
  userProfile: {
    name: string;
    email: string;
    avatar?: string;
  };
}

interface EventFormData {
  title: string;
  description: string | null;
  start: string;
  end: string;
  allDay: boolean;
  location: string | null;
  calendarId?: string;
}

interface CalendarDialogProps {
  open: boolean;
  onClose: () => void;
  onSave: (calendarData: Partial<Calendar>) => Promise<void>;
  initialData?: Partial<Calendar>;
}

function CalendarDialog({ open, onClose, onSave, initialData }: CalendarDialogProps) {
  const [name, setName] = useState(initialData?.name || "");
  const [color, setColor] = useState(initialData?.color || "#4f46e5");
  const [description, setDescription] = useState(initialData?.description || "");
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [customColorMode, setCustomColorMode] = useState(false);
  
  useEffect(() => {
    if (open) {
      setName(initialData?.name || "");
      setColor(initialData?.color || "#4f46e5");
      setDescription(initialData?.description || "");
      setCustomColorMode(!colorPalette.includes(initialData?.color || "#4f46e5"));
    }
  }, [open, initialData]);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setIsSubmitting(true);

    try {
      await onSave({ 
        id: initialData?.id,
        name, 
        color, 
        description 
      });
      resetForm();
    } catch (error) {
      console.error("Erreur lors de la création du calendrier:", error);
    } finally {
      setIsSubmitting(false);
    }
  };

  const resetForm = () => {
    setName("");
    setColor("#4f46e5");
    setDescription("");
    setCustomColorMode(false);
    onClose();
  };

  return (
    <Dialog open={open} onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="sm:max-w-md rounded-xl">
        <DialogHeader>
          <DialogTitle className="flex items-center text-xl font-semibold text-gray-900">
            <CalendarIcon className="w-5 h-5 mr-2 text-indigo-600" />
            {initialData?.id ? "Modifier le calendrier" : "Créer un nouveau calendrier"}
          </DialogTitle>
        </DialogHeader>
        
        <form onSubmit={handleSubmit}>
          <div className="space-y-5 py-4">
            <div className="space-y-2">
              <Label htmlFor="calendar-name" className="text-gray-700">Nom</Label>
              <Input
                id="calendar-name"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="Nom du calendrier"
                required
                className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
              />
            </div>

            <div className="space-y-3">
              <Label className="text-gray-700">Couleur</Label>
              
              <div className="flex flex-wrap gap-3 mb-3">
                {colorPalette.map((paletteColor) => (
                  <button
                    key={paletteColor}
                    type="button"
                    className={`w-8 h-8 rounded-full flex items-center justify-center transition-all ${
                      color === paletteColor && !customColorMode 
                        ? 'ring-2 ring-offset-2 ring-gray-400' 
                        : 'hover:scale-110'
                    }`}
                    style={{ backgroundColor: paletteColor }}
                    onClick={() => {
                      setColor(paletteColor);
                      setCustomColorMode(false);
                    }}
                  >
                    {color === paletteColor && !customColorMode && (
                      <Check className="w-4 h-4 text-white" />
                    )}
                  </button>
                ))}
                
                <button
                  type="button"
                  className={`w-8 h-8 rounded-full flex items-center justify-center bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 transition-all ${
                    customColorMode 
                      ? 'ring-2 ring-offset-2 ring-gray-400' 
                      : 'hover:scale-110'
                  }`}
                  onClick={() => setCustomColorMode(true)}
                >
                  {customColorMode && <Check className="w-4 h-4 text-white" />}
                </button>
              </div>
              
              {customColorMode && (
                <div className="flex items-center gap-4 mt-2 p-3 bg-gray-50 rounded-lg">
                  <div className="flex flex-1 items-center gap-3">
                    <Input
                      id="calendar-color"
                      type="color"
                      value={color}
                      onChange={(e) => setColor(e.target.value)}
                      className="w-10 h-10 p-1 cursor-pointer rounded border-gray-300"
                    />
                    <Input 
                      type="text"
                      value={color}
                      onChange={(e) => setColor(e.target.value)}
                      placeholder="#RRGGBB"
                      className="w-28 rounded-lg"
                    />
                  </div>
                  <div 
                    className="w-8 h-8 rounded-lg shadow-sm"
                    style={{ backgroundColor: color }}
                  ></div>
                </div>
              )}
            </div>

            <div className="space-y-2">
              <Label htmlFor="calendar-description" className="text-gray-700">
                Description (optionnelle)
              </Label>
              <Textarea
                id="calendar-description"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="Description du calendrier"
                rows={3}
                className="rounded-lg border-gray-300 focus:border-indigo-500 focus:ring-indigo-500"
              />
            </div>
          </div>

          <DialogFooter className="mt-6 border-t border-gray-100 pt-4">
            <div className="flex gap-3 w-full sm:justify-end">
              <Button
                type="button"
                variant="outline"
                onClick={onClose}
                disabled={isSubmitting}
                className="rounded-lg border-gray-300 text-gray-700 hover:bg-gray-50"
              >
                <X className="w-4 h-4 mr-2" />
                Annuler
              </Button>
              <Button 
                type="submit" 
                disabled={!name || isSubmitting}
                className="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white"
              >
                <Check className="w-4 h-4 mr-2" />
                {isSubmitting 
                  ? "Enregistrement..." 
                  : initialData?.id 
                    ? "Mettre à jour" 
                    : "Créer"
                }
              </Button>
            </div>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function StatisticsPanel({ statistics }: {
  statistics: {
    totalEvents: number;
    upcomingEvents: number;
    completedEvents: number;
    meetingHours: number;
  };
}) {
  return (
    <div className="grid grid-cols-2 gap-4 p-4">
      <Card className="p-4">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-primary/10 rounded-full">
            <CalendarIcon className="h-5 w-5 text-primary" />
          </div>
          <div>
            <p className="text-sm font-medium">Total Événements</p>
            <p className="text-2xl font-bold">{statistics.totalEvents}</p>
          </div>
        </div>
      </Card>
      <Card className="p-4">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-primary/10 rounded-full">
            <Clock className="h-5 w-5 text-primary" />
          </div>
          <div>
            <p className="text-sm font-medium">Heures de Réunion</p>
            <p className="text-2xl font-bold">{statistics.meetingHours}h</p>
          </div>
        </div>
      </Card>
      <Card className="p-4">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-primary/10 rounded-full">
            <Bell className="h-5 w-5 text-primary" />
          </div>
          <div>
            <p className="text-sm font-medium">Prochains Événements</p>
            <p className="text-2xl font-bold">{statistics.upcomingEvents}</p>
          </div>
        </div>
      </Card>
      <Card className="p-4">
        <div className="flex items-center gap-3">
          <div className="p-2 bg-primary/10 rounded-full">
            <Check className="h-5 w-5 text-primary" />
          </div>
          <div>
            <p className="text-sm font-medium">Événements Terminés</p>
            <p className="text-2xl font-bold">{statistics.completedEvents}</p>
          </div>
        </div>
      </Card>
    </div>
  );
}

function EventPreview({ event, calendar }: { event: Event; calendar: Calendar }) {
  const [isExpanded, setIsExpanded] = useState(false);

  return (
    <Card className="p-4 space-y-4">
      <div className="flex items-start justify-between">
        <div className="space-y-1">
          <h3 className="font-medium">{event.title}</h3>
          <div className="flex items-center gap-2 text-sm text-gray-500">
            <Clock className="h-4 w-4" />
            <span>
              {new Date(event.start).toLocaleDateString('fr-FR', {
                weekday: 'long',
                day: 'numeric',
                month: 'long',
                hour: '2-digit',
                minute: '2-digit'
              })}
            </span>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <div 
            className="w-3 h-3 rounded-full" 
            style={{ backgroundColor: calendar.color }}
          />
          <Button
            variant="ghost"
            size="icon"
            onClick={() => setIsExpanded(!isExpanded)}
          >
            {isExpanded ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
          </Button>
        </div>
      </div>

      {isExpanded && (
        <div className="space-y-4">
          {event.description && (
            <p className="text-sm text-gray-600">{event.description}</p>
          )}

          <div className="space-y-2">
            {event.location && (
              <div className="flex items-center gap-2 text-sm">
                <MapPin className="h-4 w-4 text-gray-500" />
                <span>{event.location}</span>
              </div>
            )}
            {event.calendarId && (
              <div className="flex items-center gap-2 text-sm">
                <Tag className="h-4 w-4 text-gray-500" />
                <span>{calendar.name}</span>
              </div>
            )}
          </div>

          <div className="flex items-center gap-2">
            <Button variant="outline" size="sm" className="flex-1">
              Modifier
            </Button>
            <Button variant="outline" size="sm" className="flex-1">
              Supprimer
            </Button>
          </div>
        </div>
      )}
    </Card>
  );
}

export function CalendarClient({ initialCalendars, userId, userProfile }: CalendarClientProps) {
  const [calendars, setCalendars] = useState(initialCalendars.map(cal => ({
    ...cal,
    events: cal.events || []
  })));
  const [selectedCalendarId, setSelectedCalendarId] = useState<string>(
    initialCalendars[0]?.id || ""
  );
  const [view, setView] = useState<"dayGridMonth" | "timeGridWeek" | "timeGridDay">("dayGridMonth");
  const [isEventModalOpen, setIsEventModalOpen] = useState(false);
  const [isCalendarModalOpen, setIsCalendarModalOpen] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState<Event | null>(null);
  const [selectedCalendar, setSelectedCalendar] = useState<Calendar | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [eventForm, setEventForm] = useState<EventFormData>({
    title: "",
    description: null,
    start: "",
    end: "",
    allDay: false,
    location: null,
    calendarId: selectedCalendarId
  });

  const [selectedEventPreview, setSelectedEventPreview] = useState<Event | null>(null);
  const [statistics, setStatistics] = useState({
    totalEvents: initialCalendars.reduce((acc, cal) => acc + cal.events.length, 0),
    upcomingEvents: initialCalendars.reduce((acc, cal) => 
      acc + cal.events.filter(e => new Date(e.start) > new Date()).length, 0
    ),
    completedEvents: initialCalendars.reduce((acc, cal) => 
      acc + cal.events.filter(e => new Date(e.end) < new Date()).length, 0
    ),
    meetingHours: initialCalendars.reduce((acc, cal) => 
      acc + cal.events.reduce((hours, e) => {
        const duration = (new Date(e.end).getTime() - new Date(e.start).getTime()) / (1000 * 60 * 60);
        return hours + duration;
      }, 0)
    , 0)
  });

  const upcomingEvents = initialCalendars
    .flatMap(cal => cal.events)
    .filter(event => new Date(event.start) > new Date())
    .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime())
    .slice(0, 5);

  const calendarRef = useRef<any>(null);

  const fetchCalendars = async () => {
    try {
      setLoading(true);
      const response = await fetch("/api/calendars");
      if (!response.ok) throw new Error("Failed to fetch calendars");
      const data = await response.json();
      console.log("Fetched calendars:", data); // Debug log
      setCalendars(data.map((cal: Calendar & { events: Event[] }) => ({
        ...cal,
        events: cal.events || []
      })));
      if (data.length > 0 && !selectedCalendarId) {
        setSelectedCalendarId(data[0].id);
      }
    } catch (error) {
      console.error("Error fetching calendars:", error);
      setError(error instanceof Error ? error.message : "Failed to fetch calendars");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchCalendars();
  }, []);

  const handleCalendarSave = async (calendarData: Partial<Calendar>) => {
    try {
      setLoading(true);
      const response = await fetch("/api/calendars", {
        method: calendarData.id ? "PUT" : "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          ...calendarData,
          userId,
        }),
      });

      if (!response.ok) {
        throw new Error("Failed to save calendar");
      }

      await fetchCalendars();
      setIsCalendarModalOpen(false);
    } catch (error) {
      console.error("Error saving calendar:", error);
      setError(error instanceof Error ? error.message : "Failed to save calendar");
    } finally {
      setLoading(false);
    }
  };

  const handleDateSelect = (selectInfo: any) => {
    const startDate = new Date(selectInfo.start);
    const endDate = new Date(selectInfo.end);
    
    setEventForm({
      title: "",
      description: null,
      start: startDate.toISOString().slice(0, 16),
      end: endDate.toISOString().slice(0, 16),
      allDay: selectInfo.allDay,
      location: null,
      calendarId: selectedCalendarId,
    });
    setIsEventModalOpen(true);
  };

  const handleEventClick = (clickInfo: any) => {
    const event = clickInfo.event;
    const startDate = new Date(event.start);
    const endDate = new Date(event.end || event.start);

    setSelectedEvent(event.extendedProps.originalEvent);
    setEventForm({
      title: event.title,
      description: event.extendedProps.description,
      start: startDate.toISOString().slice(0, 16),
      end: endDate.toISOString().slice(0, 16),
      allDay: event.isAllDay,
      location: event.extendedProps.location,
      calendarId: event.extendedProps.calendarId,
    });
    setIsEventModalOpen(true);
  };

  const handleEventSubmit = async () => {
    try {
      setLoading(true);
      const response = await fetch("/api/events", {
        method: selectedEvent ? "PUT" : "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          ...eventForm,
          calendarId: selectedCalendarId,
          userId,
        }),
      });

      if (!response.ok) {
        throw new Error("Failed to save event");
      }

      await fetchCalendars();
      setIsEventModalOpen(false);
      setEventForm({
        title: "",
        description: null,
        start: "",
        end: "",
        allDay: false,
        location: null,
        calendarId: selectedCalendarId
      });
    } catch (error) {
      console.error("Error saving event:", error);
      setError(error instanceof Error ? error.message : "Failed to save event");
    } finally {
      setLoading(false);
    }
  };

  const handleEventDelete = async () => {
    if (!selectedEvent) return;

    try {
      setLoading(true);
      const response = await fetch(`/api/events/${selectedEvent.id}`, {
        method: "DELETE",
      });

      if (!response.ok) {
        throw new Error("Failed to delete event");
      }

      await fetchCalendars();
      setIsEventModalOpen(false);
      setSelectedEvent(null);
    } catch (error) {
      console.error("Error deleting event:", error);
      setError(error instanceof Error ? error.message : "Failed to delete event");
    } finally {
      setLoading(false);
    }
  };

  const handleViewChange = (newView: "dayGridMonth" | "timeGridWeek" | "timeGridDay") => {
    setView(newView);
    if (calendarRef.current) {
      const calendarApi = calendarRef.current.getApi();
      calendarApi.changeView(newView);
    }
  };

  // Add a calendar selector component
  const CalendarSelector = () => (
    <div className="flex items-center gap-4 mb-4">
      {calendars.map((calendar) => (
        <Button
          key={calendar.id}
          variant={calendar.id === selectedCalendarId ? "secondary" : "ghost"}
          className="flex items-center gap-2"
          onClick={() => setSelectedCalendarId(calendar.id)}
        >
          <div 
            className="w-3 h-3 rounded-full" 
            style={{ backgroundColor: calendar.color }}
          />
          <span>{calendar.name}</span>
        </Button>
      ))}
    </div>
  );

  return (
    <div className="space-y-4">
      <Card className="p-4">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-4">
            <Button
              variant="outline"
              onClick={() => {
                setSelectedCalendar(null);
                setIsCalendarModalOpen(true);
              }}
              className="bg-white hover:bg-gray-50 text-gray-900 border-gray-200"
            >
              <Plus className="mr-2 h-4 w-4" />
              <span className="font-medium">Nouveau calendrier</span>
            </Button>
            <Button
              onClick={() => {
                setSelectedEvent(null);
                setEventForm({
                  title: "",
                  description: null,
                  start: "",
                  end: "",
                  allDay: false,
                  location: null,
                  calendarId: selectedCalendarId
                });
                setIsEventModalOpen(true);
              }}
              className="bg-primary hover:bg-primary/90 text-white"
            >
              <Plus className="mr-2 h-4 w-4" />
              <span className="font-medium">Nouvel événement</span>
            </Button>
          </div>

          <Tabs value={view} className="w-auto">
            <TabsList>
              <TabsTrigger
                value="dayGridMonth"
                onClick={() => handleViewChange("dayGridMonth")}
              >
                Mois
              </TabsTrigger>
              <TabsTrigger
                value="timeGridWeek"
                onClick={() => handleViewChange("timeGridWeek")}
              >
                Semaine
              </TabsTrigger>
              <TabsTrigger
                value="timeGridDay"
                onClick={() => handleViewChange("timeGridDay")}
              >
                Jour
              </TabsTrigger>
            </TabsList>
          </Tabs>
        </div>

        <CalendarSelector />

        {loading ? (
          <div className="h-96 flex items-center justify-center">
            <Loader2 className="h-8 w-8 animate-spin text-primary" />
            <span className="ml-2">Chargement des événements...</span>
          </div>
        ) : (
          <FullCalendar
            ref={calendarRef}
            plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
            initialView={view}
            headerToolbar={{
              left: "prev,next today",
              center: "title",
              right: "",
            }}
            events={calendars.flatMap(cal => 
              (cal.events || []).map(event => ({
                id: event.id,
                title: event.title,
                start: event.start,
                end: event.end,
                allDay: event.isAllDay,
                description: event.description,
                location: event.location,
                calendarId: event.calendarId,
                originalEvent: event,
                backgroundColor: cal.color,
                textColor: '#ffffff',
                borderColor: cal.color,
              }))
            )}
            locale={frLocale}
            selectable={true}
            selectMirror={true}
            dayMaxEvents={true}
            weekends={true}
            select={handleDateSelect}
            eventClick={handleEventClick}
            height="auto"
            aspectRatio={1.8}
          />
        )}
      </Card>

      {/* Calendar dialog */}
      <CalendarDialog
        open={isCalendarModalOpen}
        onClose={() => setIsCalendarModalOpen(false)}
        onSave={handleCalendarSave}
        initialData={selectedCalendar || undefined}
      />

      {/* Event dialog */}
      <Dialog open={isEventModalOpen} onOpenChange={setIsEventModalOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {selectedEvent ? "Modifier l'événement" : "Nouvel événement"}
            </DialogTitle>
          </DialogHeader>
          <div className="space-y-4 py-4">
            <div className="space-y-2">
              <label>Titre</label>
              <Input
                value={eventForm.title}
                onChange={(e) =>
                  setEventForm({ ...eventForm, title: e.target.value })
                }
              />
            </div>
            <div className="space-y-2">
              <label>Description</label>
              <Textarea
                value={eventForm.description || ""}
                onChange={(e) =>
                  setEventForm({ ...eventForm, description: e.target.value || null })
                }
              />
            </div>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <label>Début</label>
                <Input
                  type="datetime-local"
                  value={eventForm.start}
                  onChange={(e) =>
                    setEventForm({ ...eventForm, start: e.target.value })
                  }
                />
              </div>
              <div className="space-y-2">
                <label>Fin</label>
                <Input
                  type="datetime-local"
                  value={eventForm.end}
                  onChange={(e) =>
                    setEventForm({ ...eventForm, end: e.target.value })
                  }
                />
              </div>
            </div>
            <div className="space-y-2">
              <label>Lieu</label>
              <Input
                value={eventForm.location || ""}
                onChange={(e) =>
                  setEventForm({ ...eventForm, location: e.target.value || null })
                }
              />
            </div>
          </div>
          <DialogFooter className="flex justify-between">
            {selectedEvent && (
              <Button
                variant="destructive"
                onClick={handleEventDelete}
                disabled={loading}
              >
                Supprimer
              </Button>
            )}
            <div className="space-x-2">
              <Button
                variant="outline"
                onClick={() => setIsEventModalOpen(false)}
                disabled={loading}
              >
                Annuler
              </Button>
              <Button onClick={handleEventSubmit} disabled={loading}>
                {selectedEvent ? "Modifier" : "Créer"}
              </Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
