"use client";

import { useState, useRef } 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 } 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";

interface CalendarClientProps {
  initialCalendars: (Calendar & { events: Event[] })[];
  userId: string;
}

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

export function CalendarClient({ initialCalendars, userId }: CalendarClientProps) {
  const [calendars, setCalendars] = useState(initialCalendars);
  const [selectedCalendarId, setSelectedCalendarId] = useState<string>(
    initialCalendars[0]?.id || ""
  );
  const [view, setView] = useState<"dayGridMonth" | "timeGridWeek" | "timeGridDay">("dayGridMonth");
  const [isEventModalOpen, setIsEventModalOpen] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState<Event | 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,
  });

  const calendarRef = useRef<any>(null);

  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/calendar", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          title: eventForm.title,
          description: eventForm.description,
          start: eventForm.start,
          end: eventForm.end,
          isAllDay: eventForm.allDay,
          location: eventForm.location,
          calendarId: eventForm.calendarId,
        }),
      });

      if (!response.ok) {
        throw new Error("Erreur lors de la sauvegarde de l'événement");
      }

      const newEvent = await response.json();
      // Update events state with the new event
      setCalendars((prev) => prev.map(cal => ({
        ...cal,
        events: [...cal.events, newEvent]
      })));
      setIsEventModalOpen(false);
      setEventForm({
        title: "",
        description: "",
        start: "",
        end: "",
        allDay: false,
        location: "",
        calendarId: calendars[0]?.id || "",
      });
    } catch (error) {
      console.error("Error saving event:", error);
      setError(error instanceof Error ? error.message : "Une erreur est survenue");
    } finally {
      setLoading(false);
    }
  };

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

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

      if (!response.ok) {
        throw new Error("Erreur lors de la suppression de l'événement");
      }

      // Refresh calendar data
      const eventsResponse = await fetch("/api/calendar");
      const updatedEvents = await eventsResponse.json();
      setCalendars(calendars.map(cal => ({
        ...cal,
        events: updatedEvents.filter((event: Event) => event.calendarId === cal.id)
      })));

      setIsEventModalOpen(false);
      setSelectedEvent(null);
    } catch (error) {
      setError((error as Error).message);
    } finally {
      setLoading(false);
    }
  };

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

  return (
    <div className="space-y-4">
      {error && (
        <div className="p-4 mb-4 text-red-500 bg-red-50 rounded-md">
          {error}
        </div>
      )}
      {/* Calendar filters and options */}
      <div className="flex flex-wrap justify-between items-center gap-4 mb-4">
        <div className="flex flex-wrap gap-2">
          {calendars.map((calendar) => (
            <Button
              key={calendar.id}
              variant={calendar.id === selectedCalendarId ? "default" : "outline"}
              onClick={() => setSelectedCalendarId(calendar.id)}
            >
              {calendar.name}
            </Button>
          ))}
        </div>
        <Button
          onClick={() => {
            setSelectedEvent(null);
            setIsEventModalOpen(true);
          }}
        >
          <Plus className="mr-2 h-4 w-4" />
          Nouvel événement
        </Button>
      </div>

      {/* View selector */}
      <Tabs value={view} className="w-full">
        <TabsList className="mb-4">
          <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>

        {/* Calendar display */}
        <Card className="p-4">
          {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,
                }))
              )}
              locale={frLocale}
              selectable={true}
              selectMirror={true}
              dayMaxEvents={true}
              weekends={true}
              select={handleDateSelect}
              eventClick={handleEventClick}
              height="auto"
              aspectRatio={1.8}
            />
          )}
        </Card>
      </Tabs>

      {/* Event creation/edit 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>
  );
}
