
import { Document, TripMember, TripStep } from "@/types";
import { AlertCircle, CheckCircle2, Plus } from "lucide-react";
import { Button } from "@/components/ui/button";
import { TimelineDay } from "./TimelineDay";
import { useTrips } from "@/contexts/TripContext";
import { toast } from "sonner";
import { formatDate } from "@/utils/tripDataTransformers";
import { getTripDays, sortTripSteps } from "@/services/itineraryGuards";
import { useEffect, useRef } from "react";

interface TripItineraryProps {
  steps: TripStep[];
  tripId: string;
  isPlanner: boolean;
  onAddStep: (day?: number) => void;
  startDate?: string;
  endDate?: string; // Add endDate prop to the interface
  members?: TripMember[];
  documents?: Document[];
  onSelectStep?: (step: TripStep, dayDate?: string | null) => void;
  selectedDay?: number;
  selectedStepId?: string | null;
  onSelectDay?: (day: number) => void;
}

export function TripItinerary({
  steps,
  tripId,
  isPlanner,
  onAddStep,
  startDate,
  endDate,
  members,
  documents,
  onSelectStep,
  selectedDay,
  selectedStepId,
  onSelectDay,
}: TripItineraryProps) {
  const { addTripStep, deleteTripStep, updateTripStep } = useTrips();
  const dayButtonRefs = useRef<Record<number, HTMLButtonElement | null>>({});

  const visibleSteps = sortTripSteps(isPlanner ? steps : steps.filter((step) => step.isPublished));
  const stepsByDay = visibleSteps.reduce((acc, step) => {
    if (!acc[step.day]) {
      acc[step.day] = [];
    }
    acc[step.day].push(step);
    return acc;
  }, {} as { [key: number]: typeof steps });

  const tripDays = startDate && endDate ? getTripDays(startDate, endDate) : [];
  const days = tripDays.length > 0
    ? tripDays.map(({ day }) => day)
    : Object.keys(stepsByDay).map(Number).sort((a, b) => a - b);
  const activeDay = days.includes(selectedDay || 0) ? selectedDay! : days[0];

  useEffect(() => {
    if (!activeDay) return;
    dayButtonRefs.current[activeDay]?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
  }, [activeDay]);

  // Fonction pour dupliquer un jour
  const duplicateDay = async (sourceDay: number, sourceSteps: TripStep[]) => {
    try {
      const newDay = days.find((candidate) => candidate !== sourceDay && (stepsByDay[candidate]?.length || 0) === 0)
        ?? (days.length > 0 ? Math.max(...days) + 1 : 1);
      if (tripDays.length > 0 && newDay > tripDays.length) {
        throw new Error("Aucune journée disponible après la fin du voyage.");
      }

      // Dupliquer chaque étape du jour source
      for (const step of sourceSteps) {
        const stepData = {
          ...step,
          day: newDay,
          id: undefined, // L'API générera un nouvel ID
          imagePath: null, // Une image privée est liée au chemin de son étape d’origine.
          // S'assurer que les étapes dupliquées ne sont pas publiées par défaut
          isPublished: false
        };

        delete stepData.id; // Supprimer l'ID pour créer une nouvelle étape
        delete stepData.comments; // Ne pas copier les commentaires

        await addTripStep(tripId, stepData as Omit<TripStep, "id" | "comments">);
      }

      toast.success(`Jour ${sourceDay} dupliqué avec succès en jour ${newDay}!`);
    } catch (error) {
      console.error("Erreur lors de la duplication du jour:", error);
      toast.error("Erreur lors de la duplication du jour.");
    }
  };

  // Fonction pour supprimer un jour entier et réindexer les jours suivants
  const deleteDay = async (dayToDelete: number) => {
    try {
      const stepsToDelete = stepsByDay[dayToDelete] || [];

      // Supprimer chaque étape du jour
      for (const step of stepsToDelete) {
        await deleteTripStep(tripId, step.id);
      }

      // Mettre à jour les numéros de jours suivants (décrémentation)
      for (const day of days) {
        if (day > dayToDelete) {
          const stepsToUpdate = stepsByDay[day] || [];
          for (const step of stepsToUpdate) {
            await updateTripStep(tripId, step.id, { day: step.day - 1 });
          }
        }
      }

      toast.success(`Jour ${dayToDelete} supprimé avec succès!`);
    } catch (error) {
      console.error("Erreur lors de la suppression du jour:", error);
      toast.error("Erreur lors de la suppression du jour.");
    }
  };

  return <div className="min-h-[calc(100vh-15rem)] bg-card lg:grid lg:grid-cols-[220px_minmax(0,1fr)]">
    <aside className="border-b px-4 py-4 lg:border-b-0 lg:border-r lg:px-3" aria-label="Journées du voyage">
      <div className="mb-3 flex items-center justify-between px-2"><h2 className="text-xs font-semibold uppercase tracking-[.14em] text-muted-foreground">Journées</h2><span className="text-xs text-muted-foreground">{days.length}</span></div>
      <div className="flex snap-x snap-mandatory gap-2 overflow-x-auto overscroll-x-contain pb-2 touch-pan-x lg:block lg:space-y-1 lg:overflow-visible">
        {days.map((day) => { const date = tripDays.find((item) => item.day === day)?.date; const daySteps = stepsByDay[day] || []; const needsAttention = daySteps.some((step) => step.comments.length || (step.validations || []).some((v) => v.status === "rejected")); return <button ref={(node) => { dayButtonRefs.current[day] = node; }} key={day} type="button" aria-current={day === activeDay ? "date" : undefined} onClick={() => onSelectDay?.(day)} className={`min-w-[148px] shrink-0 snap-center rounded-lg px-3 py-3 text-left transition lg:w-full ${day === activeDay ? "bg-muted font-medium text-foreground ring-1 ring-border" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground"}`}><span className="flex items-center justify-between"><strong className="text-sm">Jour {day}</strong>{needsAttention ? <AlertCircle className="h-4 w-4 text-amber-600" aria-label="Attention requise" /> : daySteps.length > 0 ? <CheckCircle2 className="h-4 w-4 text-muted-foreground" aria-label="Journée renseignée" /> : null}</span>{date && <span className="mt-1 block text-xs capitalize">{formatDate(date)}</span>}<span className="mt-1 block truncate text-xs">{daySteps[0]?.location || `${daySteps.length} étape(s)`}</span></button>; })}
      </div>
      <Button variant="ghost" size="sm" className="mt-3 w-full justify-start" disabled title="Les journées suivent les dates du voyage"><Plus className="mr-2 h-4 w-4" />Ajouter une journée</Button>
    </aside>
    <main className="min-w-0 px-4 py-6 sm:px-6 lg:px-8">
      <p className="mb-5 text-sm text-muted-foreground">{isPlanner ? "Publiez une étape lorsqu’elle est prête à être partagée avec les voyageurs." : "Consultez les étapes publiées de votre voyage. Approuvez ou refusez une étape pour transmettre votre avis."}</p>
      {activeDay ? <TimelineDay
                key={activeDay}
                day={activeDay}
                steps={stepsByDay[activeDay] || []}
                tripId={tripId}
                isPlanner={isPlanner}
                onAddStep={onAddStep}
                startDate={startDate}
                dayDate={tripDays.find((candidate) => candidate.day === activeDay)?.date}
                onDuplicateDay={duplicateDay}
                onDeleteDay={deleteDay}
                members={members}
                documents={documents}
                onSelectStep={onSelectStep}
                selectedStepId={selectedStepId}
              /> : <div className="py-16 text-center"><h2 className="text-lg font-semibold">Votre itinéraire est encore vide</h2><p className="mt-2 text-sm text-muted-foreground">Définissez d’abord les dates du voyage pour organiser ses journées.</p></div>}
    </main>
  </div>;
}
