"use client";

import { useState, useEffect, 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 { useCalendarEvents } from "@/hooks/use-calendar-events";
import { EventDialog } from "@/components/calendar/event-dialog";
import { Calendar as CalendarType } from "@prisma/client";
import { useToast } from "@/components/ui/use-toast";

interface CalendarClientProps {
  initialCalendars: CalendarType[];
}

export function CalendarClient({ initialCalendars }: CalendarClientProps) {
  const [calendars, setCalendars] = useState<CalendarType[]>(initialCalendars);
  const [selectedCalendarId, setSelectedCalendarId] = useState<string>(
    initialCalendars[0]?.id || ""
  );
  const [view, setView] = useState<
    "dayGridMonth" | "timeGridWeek" | "timeGridDay"
  >("dayGridMonth");
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState<any>(null);
  const [dateRange, setDateRange] = useState({
    start: new Date(),
    end: new Date(new Date().setMonth(new Date().getMonth() + 1)),
  });

  const calendarRef = useRef<any>(null);
  const { toast } = useToast();

  const {
    events,
    loading,
    error,
    refresh,
    createEvent,
    updateEvent,
    deleteEvent,
  } = useCalendarEvents(selectedCalendarId, dateRange.start, dateRange.end);

  // Mettre à jour la plage de dates lorsque la vue change
  const handleDatesSet = (arg: any) => {
    setDateRange({
      start: arg.start,
      end: arg.end,
    });
  };

  // Gérer la sélection d'une plage de dates pour créer un événement
  const handleDateSelect = (selectInfo: any) => {
    setSelectedEvent({
      start: selectInfo.startStr,
      end: selectInfo.endStr,
      allDay: selectInfo.allDay,
    });
    setIsDialogOpen(true);
  };

  // Gérer le clic sur un événement existant
  const handleEventClick = (clickInfo: any) => {
    setSelectedEvent({
      id: clickInfo.event.id,
      title: clickInfo.event.title,
      description: clickInfo.event.extendedProps.description,
      start: clickInfo.event.startStr,
      end: clickInfo.event.endStr,
      location: clickInfo.event.extendedProps.location,
      allDay: clickInfo.event.allDay,
    });
    setIsDialogOpen(true);
  };

  // Gérer la création ou mise à jour d'un événement
  const handleEventSave = async (eventData: any) => {
    try {
      if (eventData.id) {
        await updateEvent(eventData);
        toast({
          title: "Événement mis à jour",
          description: "L'événement a été modifié avec succès.",
        });
      } else {
        await createEvent({
          ...eventData,
          calendarId: selectedCalendarId,
        });
        toast({
          title: "Événement créé",
          description: "L'événement a été ajouté au calendrier.",
        });
      }
      setIsDialogOpen(false);
      refresh();
    } catch (error) {
      console.error("Erreur lors de la sauvegarde de l'événement:", error);
      toast({
        title: "Erreur",
        description: "Impossible d'enregistrer l'événement.",
        variant: "destructive",
      });
    }
  };

  // Gérer la suppression d'un événement
  const handleEventDelete = async (eventId: string) => {
    try {
      await deleteEvent(eventId);
      toast({
        title: "Événement supprimé",
        description: "L'événement a été supprimé du calendrier.",
      });
      setIsDialogOpen(false);
      refresh();
    } catch (error) {
      console.error("Erreur lors de la suppression de l'événement:", error);
      toast({
        title: "Erreur",
        description: "Impossible de supprimer l'événement.",
        variant: "destructive",
      });
    }
  };

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

  // Changer le calendrier sélectionné
  const handleCalendarChange = (calendarId: string) => {
    setSelectedCalendarId(calendarId);
  };

  return (
    <div className='space-y-4'>
      {/* Options et filtres du calendrier */}
      <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={() => handleCalendarChange(calendar.id)}
              style={{
                backgroundColor:
                  calendar.id === selectedCalendarId
                    ? calendar.color
                    : undefined,
                borderColor: calendar.color,
              }}
            >
              {calendar.name}
            </Button>
          ))}
        </div>
        <Button
          onClick={() => {
            setSelectedEvent(null);
            setIsDialogOpen(true);
          }}
        >
          <Plus className='mr-2 h-4 w-4' />
          Nouvel événement
        </Button>
      </div>

      {/* Sélecteur de vue */}
      <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>

        {/* Affichage du calendrier */}
        <Card className='p-4'>
          {error && (
            <div className='p-4 mb-4 text-red-500 bg-red-50 rounded-md'>
              Erreur: {error.message}
            </div>
          )}

          {loading && !events.length ? (
            <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={events.map((event) => ({
                id: event.id,
                title: event.title,
                start: event.start,
                end: event.end,
                allDay: event.isAllDay,
                extendedProps: {
                  description: event.description,
                  location: event.location,
                },
              }))}
              selectable={true}
              selectMirror={true}
              dayMaxEvents={true}
              weekends={true}
              locale={frLocale}
              select={handleDateSelect}
              eventClick={handleEventClick}
              datesSet={handleDatesSet}
              height='auto'
              aspectRatio={1.8}
            />
          )}
        </Card>
      </Tabs>

      {/* Dialogue pour créer/modifier un événement */}
      {isDialogOpen && (
        <EventDialog
          open={isDialogOpen}
          event={selectedEvent}
          onClose={() => setIsDialogOpen(false)}
          onSave={handleEventSave}
          onDelete={selectedEvent?.id ? handleEventDelete : undefined}
        />
      )}
    </div>
  );
}
