"use client";

import { useState, useEffect, useRef } from "react";
import { format, isToday, isTomorrow, addDays } from "date-fns";
import { fr } from "date-fns/locale";
import { CalendarIcon, ChevronRight } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import { useSession } from "next-auth/react";
import { useWidgetNotification } from "@/hooks/use-widget-notification";

type Event = {
  id: string;
  title: string;
  start: string | Date;
  end: string | Date;
  isAllDay: boolean;
  calendarId: string;
  calendarName?: string;
  calendarColor?: string;
};

export function CalendarWidget() {
  const { data: session } = useSession();
  const [events, setEvents] = useState<Event[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const { triggerNotification } = useWidgetNotification();
  const lastEventCountRef = useRef<number>(-1);

  useEffect(() => {
    // Ne charger les événements que si l'utilisateur est connecté
    if (!session) return;

    const fetchUpcomingEvents = async () => {
      try {
        setLoading(true);
        
        // Récupérer d'abord les calendriers de l'utilisateur
        const calendarsRes = await fetch("/api/calendars");

        if (!calendarsRes.ok) {
          throw new Error("Impossible de charger les calendriers");
        }

        const calendars = await calendarsRes.json();
        
        if (calendars.length === 0) {
          setEvents([]);
          setLoading(false);
          return;
        }

        // Date actuelle et date dans 7 jours
        const now = new Date();
        const nextWeek = addDays(now, 7);
        
        // Helper function to get display name for calendar
        const getCalendarDisplayName = (calendar: any) => {
          // If calendar is synced to an external account, use the account name
          if (calendar.syncConfig?.syncEnabled && calendar.syncConfig?.mailCredential) {
            return calendar.syncConfig.mailCredential.display_name || 
                   calendar.syncConfig.mailCredential.email;
          }
          // For non-synced calendars, use the calendar name
          return calendar.name;
        };

        // Récupérer les événements pour chaque calendrier
        const allEventsPromises = calendars.map(async (calendar: any) => {
          const eventsRes = await fetch(
            `/api/calendars/${
              calendar.id
            }/events?start=${now.toISOString()}&end=${nextWeek.toISOString()}`
          );

          if (!eventsRes.ok) {
            console.warn(
              `Impossible de charger les événements du calendrier ${calendar.id}`
            );
            return [];
          }

          const events = await eventsRes.json();

          // Ajouter les informations du calendrier à chaque événement
          return events.map((event: any) => ({
            ...event,
            calendarName: getCalendarDisplayName(calendar),
              calendarColor: calendar.color,
          }));
        });

        // Attendre toutes les requêtes d'événements
        const allEventsArrays = await Promise.all(allEventsPromises);

        // Fusionner tous les événements en un seul tableau
        const allEvents = allEventsArrays.flat();

        // Trier par date de début
        const sortedEvents = allEvents.sort(
          (a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()
        );

        // Limiter à 5 événements pour l'affichage
        const upcomingEvents = sortedEvents.slice(0, 5);
        
        // Calculate current event count (all events, not just displayed)
        const currentEventCount = sortedEvents.length;
          
        // Prepare notification items for all upcoming events
        const notificationItems = sortedEvents.map(event => ({
          id: event.id,
          title: event.title,
          message: event.isAllDay
            ? `Aujourd'hui (toute la journée)`
            : `Le ${format(new Date(event.start), 'dd/MM à HH:mm', { locale: fr })}`,
          link: '/agenda',
          timestamp: new Date(event.start),
          metadata: {
            calendarId: event.calendarId,
            calendarName: event.calendarName,
            isAllDay: event.isAllDay,
          },
        }));

        // Always trigger notification update to keep count fresh in Redis
        await triggerNotification({
          source: 'calendar',
          count: currentEventCount,
          items: notificationItems,
        });
        
        // Update last count reference
        if (currentEventCount !== lastEventCountRef.current) {
          lastEventCountRef.current = currentEventCount;
        }
        
        setEvents(upcomingEvents);
        
        // Dispatch event for Outlook-style notifications
        const eventsForNotification = sortedEvents.map(evt => ({
          id: evt.id,
          title: evt.title,
          start: new Date(evt.start),
          end: new Date(evt.end),
          isAllDay: evt.isAllDay,
          calendarName: evt.calendarName,
          calendarColor: evt.calendarColor,
        }));
        
        try {
          window.dispatchEvent(new CustomEvent('calendar-events-updated', {
            detail: {
              events: eventsForNotification,
            }
          }));
        } catch (error) {
          console.error('[Calendar Widget] Error dispatching event', error);
        }
        
        setError(null);
      } catch (err) {
        console.error("Calendar Widget - Error in fetchUpcomingEvents:", err);
        setError("Impossible de charger les événements à venir");
      } finally {
        setLoading(false);
      }
    };

    fetchUpcomingEvents();
  }, [session]);

  const formatEventDate = (date: string | Date, isAllDay: boolean) => {
    const eventDate = new Date(date);

    let dateString = "";
    if (isToday(eventDate)) {
      dateString = "Aujourd'hui";
    } else if (isTomorrow(eventDate)) {
      dateString = "Demain";
    } else {
      dateString = format(eventDate, "EEEE d MMMM", { locale: fr });
    }

    if (!isAllDay) {
      dateString += ` · ${format(eventDate, "HH:mm", { locale: fr })}`;
    }

    return dateString;
  };

  return (
    <Card className='transition-transform duration-500 ease-in-out transform hover:scale-105'>
      <CardHeader className='flex flex-row items-center justify-between pb-2'>
        <CardTitle className='text-lg font-medium'>
          Événements à venir
        </CardTitle>
        <Link href='/calendar' passHref>
          <Button variant='ghost' size='sm' className='h-8 w-8 p-0'>
            <ChevronRight className='h-4 w-4' />
            <span className='sr-only'>Voir le calendrier</span>
          </Button>
        </Link>
      </CardHeader>
      <CardContent className='pb-3'>
        {loading ? (
          <div className='flex items-center justify-center py-4'>
            <div className='h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent' />
            <span className='ml-2 text-sm text-muted-foreground'>
              Chargement...
            </span>
          </div>
        ) : error ? (
          <p className='text-sm text-red-500'>{error}</p>
        ) : events.length === 0 ? (
          <p className='text-sm text-muted-foreground py-2'>
            Aucun événement à venir cette semaine
          </p>
        ) : (
          <div className='space-y-3'>
            {events.map((event) => (
              <div
                key={event.id}
                className='flex items-start space-x-3 rounded-md border border-muted p-2'
              >
                <div
                  className='h-3 w-3 flex-shrink-0 rounded-full mt-1'
                  style={{ backgroundColor: event.calendarColor || "#0082c9" }}
                />
                <div className='flex-1 min-w-0'>
                  <h5
                    className='text-sm font-medium truncate'
                    title={event.title}
                  >
                    {event.title}
                  </h5>
                  <div className='flex items-center text-xs text-muted-foreground mt-1'>
                    <CalendarIcon className='h-3 w-3 mr-1' />
                    <span>{formatEventDate(event.start, event.isAllDay)}</span>
                  </div>
                </div>
              </div>
            ))}
            <Link href='/calendar' passHref>
              <Button
                size='sm'
                className='w-full transition-all ease-in-out duration-500 bg-muted text-black hover:text-white hover:bg-primary'
              >
                Voir tous les événements
              </Button>
            </Link>
          </div>
        )}
      </CardContent>
    </Card>
  );
}