import { useState } from "react";
import DashboardLayout from "@/components/DashboardLayout";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { trpc } from "@/lib/trpc";
import { ChevronLeft, ChevronRight, Calendar as CalendarIcon, Filter, Download } from "lucide-react";
import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameMonth, isSameDay, parseISO, addMonths, subMonths, startOfWeek, endOfWeek, addWeeks, subWeeks, addDays, subDays } from "date-fns";
import { fr } from "date-fns/locale";

type ViewMode = 'month' | 'week' | 'day';

export default function AdminCalendrier() {
  const [currentDate, setCurrentDate] = useState(new Date());
  const [selectedSequence, setSelectedSequence] = useState<any>(null);
  const [isDetailOpen, setIsDetailOpen] = useState(false);
  const [viewMode, setViewMode] = useState<ViewMode>('month');
  const [filterFormation, setFilterFormation] = useState<string>('all');
  const [filterLieu, setFilterLieu] = useState<string>('all');
  const [filterPublicCible, setFilterPublicCible] = useState<string>('all');

  const { data: sequences, isLoading } = trpc.sequences.list.useQuery();
  const { data: formations } = trpc.formations.list.useQuery();

  // Filtrer les séquences selon les critères
  const filteredSequences = sequences?.filter((seq) => {
    if (filterFormation !== 'all' && seq.formationId !== parseInt(filterFormation)) return false;
    if (filterLieu !== 'all' && seq.lieu !== filterLieu) return false;
    if (filterPublicCible !== 'all' && seq.publicCible !== filterPublicCible) return false;
    return true;
  }) || [];

  // Extraire les lieux uniques pour le filtre
  const uniqueLieux = Array.from(new Set(sequences?.map(s => s.lieu).filter(Boolean))) as string[];

  // Extraire les publics cibles uniques
  const uniquePublicsCibles = Array.from(new Set(sequences?.map(s => s.publicCible).filter(Boolean))) as string[];

  const monthStart = startOfMonth(currentDate);
  const monthEnd = endOfMonth(currentDate);
  const daysInMonth = eachDayOfInterval({ start: monthStart, end: monthEnd });

  // Obtenir le premier jour de la semaine (lundi = 0)
  const firstDayOfWeek = (monthStart.getDay() + 6) % 7;

  // Créer un tableau avec les jours vides au début
  const calendarDays = [
    ...Array(firstDayOfWeek).fill(null),
    ...daysInMonth,
  ];

  const getSequencesForDay = (day: Date) => {
    if (!filteredSequences) return [];
    return filteredSequences.filter((seq) => {
      if (!seq.dates || seq.dates.length === 0) return false;
      return seq.dates.some((dateForm: any) => {
        // Gérer le cas où dateDebut est déjà un objet Date ou une chaîne
        let dateDebut: Date;
        if (typeof dateForm.dateDebut === 'string') {
          dateDebut = parseISO(dateForm.dateDebut);
        } else if (dateForm.dateDebut instanceof Date) {
          dateDebut = dateForm.dateDebut;
        } else {
          return false;
        }
        return isSameDay(dateDebut, day);
      });
    });
  };

  const handlePrevious = () => {
    if (viewMode === 'month') {
      setCurrentDate(subMonths(currentDate, 1));
    } else if (viewMode === 'week') {
      setCurrentDate(subWeeks(currentDate, 1));
    } else {
      setCurrentDate(subDays(currentDate, 1));
    }
  };

  const handleNext = () => {
    if (viewMode === 'month') {
      setCurrentDate(addMonths(currentDate, 1));
    } else if (viewMode === 'week') {
      setCurrentDate(addWeeks(currentDate, 1));
    } else {
      setCurrentDate(addDays(currentDate, 1));
    }
  };

  const handleSequenceClick = (sequence: any) => {
    setSelectedSequence(sequence);
    setIsDetailOpen(true);
  };

  const handleExportPDF = () => {
    window.print();
  };

  const handleExportICal = () => {
    const icalContent = [
      'BEGIN:VCALENDAR',
      'VERSION:2.0',
      'PRODID:-//Formation Manager Itinova//FR',
      'CALSCALE:GREGORIAN',
      'METHOD:PUBLISH',
      'X-WR-CALNAME:Calendrier des formations',
      'X-WR-TIMEZONE:Europe/Paris',
    ];

    filteredSequences.forEach((seq) => {
      if (seq.dates && seq.dates.length > 0) {
        seq.dates.forEach((dateForm: any) => {
          const dateDebut = typeof dateForm.dateDebut === 'string' ? parseISO(dateForm.dateDebut) : dateForm.dateDebut;
          const dateFin = typeof dateForm.dateFin === 'string' ? parseISO(dateForm.dateFin) : dateForm.dateFin;
          
          const dtstart = format(dateDebut, "yyyyMMdd'T'HHmmss");
          const dtend = format(dateFin, "yyyyMMdd'T'HHmmss");
          
          icalContent.push(
            'BEGIN:VEVENT',
            `UID:${seq.id}-${dateForm.id || Math.random()}@formation-manager.itinova`,
            `DTSTAMP:${format(new Date(), "yyyyMMdd'T'HHmmss'Z'")}`,
            `DTSTART:${dtstart}`,
            `DTEND:${dtend}`,
            `SUMMARY:${seq.nom}`,
            `DESCRIPTION:${seq.formation?.nom || 'Formation'} - ${seq.nbInscrits || 0}/${seq.capaciteMax} inscrits`,
            `LOCATION:${seq.lieu}`,
            'STATUS:CONFIRMED',
            'SEQUENCE:0',
            'END:VEVENT'
          );
        });
      }
    });

    icalContent.push('END:VCALENDAR');
    
    const blob = new Blob([icalContent.join('\r\n')], { type: 'text/calendar;charset=utf-8' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `calendrier-formations-${format(currentDate, "yyyy-MM")}.ics`;
    link.click();
  };

  const getPublicCibleLabel = (publicCible: string) => {
    const labels: Record<string, string> = {
      directeurs: "Directeurs",
      chefs_service: "Chefs de service",
      tous: "Tous",
      autre: "Autre",
    };
    return labels[publicCible] || publicCible;
  };

  const getStatutBadge = (statut: string) => {
    const badges: Record<string, string> = {
      ouverte: "bg-green-100 text-green-800",
      fermee: "bg-red-100 text-red-800",
      annulee: "bg-gray-100 text-gray-800",
    };
    return badges[statut] || "bg-blue-100 text-blue-800";
  };

  return (
    <DashboardLayout>
      <div className="space-y-6">
        <div>
          <h1 className="page-title">Calendrier des séquences</h1>
          <p className="text-muted-foreground">
            Vue mensuelle de toutes les séquences planifiées
          </p>
        </div>

        {/* Filtres */}
        <Card>
          <CardHeader>
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <div>
                  <CardTitle className="flex items-center gap-2">
                    <CalendarIcon className="h-5 w-5" />
                    Calendrier des séquences
                  </CardTitle>
                  <CardDescription>
                    Cliquez sur une séquence pour voir les détails
                  </CardDescription>
                </div>
                <div className="flex gap-2">
                  <Select value={viewMode} onValueChange={(value) => setViewMode(value as ViewMode)}>
                    <SelectTrigger className="w-[130px]">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="month">Mois</SelectItem>
                      <SelectItem value="week">Semaine</SelectItem>
                      <SelectItem value="day">Jour</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {/* Barre de filtres */}
              <div className="flex items-center gap-3 flex-wrap">
                <div className="flex items-center gap-2">
                  <Filter className="h-4 w-4 text-muted-foreground" />
                  <span className="text-sm font-medium">Filtres :</span>
                </div>
                <Select value={filterFormation} onValueChange={setFilterFormation}>
                  <SelectTrigger className="w-[200px]">
                    <SelectValue placeholder="Formation" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">Toutes les formations</SelectItem>
                    {formations?.map((formation) => (
                      <SelectItem key={formation.id} value={formation.id.toString()}>
                        {formation.nom}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <Select value={filterLieu} onValueChange={setFilterLieu}>
                  <SelectTrigger className="w-[180px]">
                    <SelectValue placeholder="Lieu" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">Tous les lieux</SelectItem>
                    {uniqueLieux.map((lieu) => (
                      <SelectItem key={lieu} value={lieu}>
                        {lieu}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <Select value={filterPublicCible} onValueChange={setFilterPublicCible}>
                  <SelectTrigger className="w-[180px]">
                    <SelectValue placeholder="Public cible" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">Tous les publics</SelectItem>
                    {uniquePublicsCibles.map((pc) => (
                      <SelectItem key={pc} value={pc}>
                        {getPublicCibleLabel(pc)}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {(filterFormation !== 'all' || filterLieu !== 'all' || filterPublicCible !== 'all') && (
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      setFilterFormation('all');
                      setFilterLieu('all');
                      setFilterPublicCible('all');
                    }}
                  >
                    Réinitialiser
                  </Button>
                )}
              </div>

              {/* Navigation et exports */}
              <div className="flex items-center justify-between">
                <h3 className="text-lg font-semibold">
                  {viewMode === 'month' && format(currentDate, "MMMM yyyy", { locale: fr })}
                  {viewMode === 'week' && `Semaine du ${format(startOfWeek(currentDate, { locale: fr }), "d MMM", { locale: fr })}`}
                  {viewMode === 'day' && format(currentDate, "EEEE d MMMM yyyy", { locale: fr })}
                </h3>
                <div className="flex gap-2">
                  <Button variant="outline" size="sm" onClick={handleExportPDF}>
                    <Download className="h-4 w-4 mr-2" />
                    PDF
                  </Button>
                  <Button variant="outline" size="sm" onClick={handleExportICal}>
                    <Download className="h-4 w-4 mr-2" />
                    iCal
                  </Button>
                  <div className="border-l mx-1" />
                  <Button variant="outline" size="icon" onClick={handlePrevious}>
                    <ChevronLeft className="h-4 w-4" />
                  </Button>
                  <Button
                    variant="outline"
                    onClick={() => setCurrentDate(new Date())}
                  >
                    Aujourd'hui
                  </Button>
                  <Button variant="outline" size="icon" onClick={handleNext}>
                    <ChevronRight className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            </div>
          </CardHeader>
          <CardContent>
            {isLoading ? (
              <div className="text-center py-8">Chargement...</div>
            ) : viewMode === 'month' ? (
              <div className="grid grid-cols-7 gap-2">
                {/* En-têtes des jours */}
                {["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"].map((day) => (
                  <div
                    key={day}
                    className="text-center font-semibold text-sm text-muted-foreground py-2"
                  >
                    {day}
                  </div>
                ))}

                {/* Jours du calendrier */}
                {calendarDays.map((day, index) => {
                  if (!day) {
                    return <div key={`empty-${index}`} className="min-h-[100px]" />;
                  }

                  const daySequences = getSequencesForDay(day);
                  const isToday = isSameDay(day, new Date());
                  const dayKey = format(day, "yyyy-MM-dd");

                  return (
                    <div
                      key={dayKey}
                      className={`min-h-[100px] border rounded-lg p-2 ${
                        !isSameMonth(day, currentDate)
                          ? "bg-muted/50"
                          : isToday
                          ? "bg-blue-50 border-blue-300"
                          : "bg-background"
                      }`}
                    >
                      <div className="font-semibold text-sm mb-1">
                        {format(day, "d")}
                      </div>
                      <div className="space-y-1">
                        {daySequences.map((seq) => (
                          <button
                            key={seq.id}
                            onClick={() => handleSequenceClick(seq)}
                            className="w-full text-left text-xs p-1.5 rounded bg-blue-100 hover:bg-blue-200 text-blue-800 space-y-0.5"
                          >
                            <div className="font-medium truncate">{seq.nom}</div>
                            <div className="text-[10px] font-semibold opacity-90 truncate">{seq.formation?.nom || "Sans formation"}</div>
                            <div className="text-[10px] opacity-80 truncate">
                              {seq.lieu} {seq.formateur && `• ${seq.formateur}`}
                            </div>
                            <div className="text-[10px] opacity-80">
                              {seq.nbInscrits || 0}/{seq.capaciteMax} inscrits
                            </div>
                          </button>
                        ))}
                      </div>
                    </div>
                  );
                })}
              </div>
            ) : viewMode === 'week' ? (
              <div className="space-y-4">
                <div className="grid grid-cols-8 gap-2">
                  <div className="text-center font-semibold text-sm text-muted-foreground py-2">Heure</div>
                  {Array.from({ length: 7 }).map((_, i) => {
                    const day = addDays(startOfWeek(currentDate, { locale: fr }), i);
                    return (
                      <div key={i} className="text-center">
                        <div className="font-semibold text-sm">{format(day, "EEE", { locale: fr })}</div>
                        <div className="text-xs text-muted-foreground">{format(day, "d MMM", { locale: fr })}</div>
                      </div>
                    );
                  })}
                </div>
                <div className="text-sm text-muted-foreground text-center py-8">
                  Vue hebdomadaire - Affichage des séquences par jour
                </div>
                {Array.from({ length: 7 }).map((_, i) => {
                  const day = addDays(startOfWeek(currentDate, { locale: fr }), i);
                  const daySequences = getSequencesForDay(day);
                  return daySequences.length > 0 ? (
                    <div key={i} className="space-y-2">
                      <h4 className="font-medium text-sm">{format(day, "EEEE d MMMM", { locale: fr })}</h4>
                      <div className="grid gap-2">
                        {daySequences.map((seq) => (
                          <button
                            key={seq.id}
                            onClick={() => handleSequenceClick(seq)}
                            className="w-full text-left p-3 rounded-lg border bg-card hover:bg-accent transition-colors"
                          >
                            <div className="font-medium">{seq.nom}</div>
                            <div className="text-sm text-muted-foreground">{seq.formation?.nom || "Sans formation"}</div>
                            <div className="text-sm text-muted-foreground">
                              {seq.lieu} • {seq.nbInscrits || 0}/{seq.capaciteMax} inscrits
                            </div>
                          </button>
                        ))}
                      </div>
                    </div>
                  ) : null;
                })}
              </div>
            ) : (
              <div className="space-y-4">
                <div className="text-center">
                  <h3 className="text-lg font-semibold">{format(currentDate, "EEEE d MMMM yyyy", { locale: fr })}</h3>
                </div>
                {getSequencesForDay(currentDate).length > 0 ? (
                  <div className="grid gap-3">
                    {getSequencesForDay(currentDate).map((seq) => (
                      <button
                        key={seq.id}
                        onClick={() => handleSequenceClick(seq)}
                        className="w-full text-left p-4 rounded-lg border bg-card hover:bg-accent transition-colors"
                      >
                        <div className="flex items-start justify-between">
                          <div className="flex-1">
                            <div className="font-semibold text-lg">{seq.nom}</div>
                            <div className="text-sm text-muted-foreground mt-1">{seq.formation?.nom || "Sans formation"}</div>
                            <div className="flex items-center gap-4 mt-2 text-sm">
                              <span>📍 {seq.lieu}</span>
                              <span>👥 {seq.nbInscrits || 0}/{seq.capaciteMax} inscrits</span>
                              {seq.formateur && <span>👨‍🏫 {typeof seq.formateur === 'object' ? seq.formateur.nom : seq.formateur}</span>}
                            </div>
                          </div>
                        </div>
                      </button>
                    ))}
                  </div>
                ) : (
                  <div className="text-center py-12 text-muted-foreground">
                    Aucune séquence prévue pour ce jour
                  </div>
                )}
              </div>
            )}
          </CardContent>
        </Card>

        {/* Dialog de détails */}
        <Dialog open={isDetailOpen} onOpenChange={setIsDetailOpen}>
          <DialogContent className="max-w-2xl">
            <DialogHeader>
              <DialogTitle>Détails de la séquence</DialogTitle>
              <DialogDescription>
                Informations complètes sur la séquence sélectionnée
              </DialogDescription>
            </DialogHeader>
            {selectedSequence && (
              <div className="space-y-4">
                <div>
                  <h3 className="font-semibold text-lg">
                    {selectedSequence.formation?.nom || "Sans titre"}
                  </h3>
                  <p className="text-sm text-muted-foreground">
                    {selectedSequence.formation?.description || "Aucune description"}
                  </p>
                </div>

                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <p className="text-sm font-medium text-muted-foreground">Lieu</p>
                    <p className="text-sm">{selectedSequence.lieu}</p>
                  </div>
                  <div>
                    <p className="text-sm font-medium text-muted-foreground">Public cible</p>
                    <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
                      {getPublicCibleLabel(selectedSequence.publicCible)}
                    </span>
                  </div>
                  <div>
                    <p className="text-sm font-medium text-muted-foreground">Capacité</p>
                    <p className="text-sm">
                      {selectedSequence.nbInscrits || 0} / {selectedSequence.capaciteMax}
                    </p>
                  </div>
                  <div>
                    <p className="text-sm font-medium text-muted-foreground">Statut</p>
                    <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getStatutBadge(selectedSequence.statut)}`}>
                      {selectedSequence.statut}
                    </span>
                  </div>
                  {selectedSequence.formateur && (
                    <div>
                      <p className="text-sm font-medium text-muted-foreground">Formateur</p>
                      <p className="text-sm">
                        {typeof selectedSequence.formateur === 'object' && selectedSequence.formateur !== null
                          ? selectedSequence.formateur.nom || String(selectedSequence.formateur)
                          : selectedSequence.formateur
                        }
                      </p>
                    </div>
                  )}
                  {selectedSequence.dateBloquage && (
                    <div>
                      <p className="text-sm font-medium text-muted-foreground">Date de blocage</p>
                      <p className="text-sm">
                        {typeof selectedSequence.dateBloquage === 'string' 
                          ? format(parseISO(selectedSequence.dateBloquage), "dd/MM/yyyy", { locale: fr })
                          : format(selectedSequence.dateBloquage, "dd/MM/yyyy", { locale: fr })
                        }
                      </p>
                    </div>
                  )}
                </div>

                {selectedSequence.dates && selectedSequence.dates.length > 0 && (
                  <div>
                    <p className="text-sm font-medium text-muted-foreground mb-2">Dates de formation</p>
                    <div className="space-y-1">
                      {selectedSequence.dates.map((dateForm: any, index: number) => {
                        const dateDebut = typeof dateForm.dateDebut === 'string' ? parseISO(dateForm.dateDebut) : dateForm.dateDebut;
                        const dateFin = typeof dateForm.dateFin === 'string' ? parseISO(dateForm.dateFin) : dateForm.dateFin;
                        const dateKey = `${selectedSequence.id}-date-${index}`;
                        return (
                          <div key={dateKey} className="text-sm bg-muted p-2 rounded">
                            Du {format(dateDebut, "dd/MM/yyyy", { locale: fr })} au{" "}
                            {format(dateFin, "dd/MM/yyyy", { locale: fr })}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            )}
          </DialogContent>
        </Dialog>
      </div>
    </DashboardLayout>
  );
}
