import { useEffect, useMemo, useRef, useState } from "react";
import { Link, Navigate, useParams, useSearchParams } from "react-router-dom";
import { ArrowDown, Check, ChevronLeft, ChevronRight, ExternalLink, Eye, FileText, MapPin, MessageCircle, X } from "lucide-react";
import { toast } from "sonner";
import { useTrips } from "@/contexts/TripContext";
import { useAuth } from "@/contexts/AuthContext";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { StepComments } from "@/components/dashboard/StepComments";
import { DocumentItem } from "@/components/dashboard/DocumentItem";
import { StepImage, StepImageThumbnail } from "@/components/dashboard/step/StepImage";
import { buildMapsUrl, getDefaultTripDay, getPublishedSteps, getTravelerValidation, getTripDayCount, getTripDayLabel, getVisibleDocuments } from "@/services/travelerViewModel";
import type { TripStep } from "@/types";

const formatDateRange = (start: string, end: string) => `${new Date(`${start}T12:00:00`).toLocaleDateString("fr-FR", { day: "numeric", month: "long" })} — ${new Date(`${end}T12:00:00`).toLocaleDateString("fr-FR", { day: "numeric", month: "long", year: "numeric" })}`;

export default function TravelerTripDetailPage({ preview = false }: { preview?: boolean }) {
  const { tripId } = useParams<{ tripId: string }>();
  const { getTrip, isLoading, error, refetchTrips, validateTripStep } = useTrips();
  const { currentUser } = useAuth();
  const [searchParams, setSearchParams] = useSearchParams();
  const [conversation, setConversation] = useState<{ step: TripStep; initialMessage?: string } | null>(null);
  const [validating, setValidating] = useState<string | null>(null);
  const trip = tripId ? getTrip(tripId) : undefined;
  const publishedSteps = useMemo(() => trip ? getPublishedSteps(trip) : [], [trip]);
  const dayCount = trip ? getTripDayCount(trip) : 1;
  const requestedDay = Number(searchParams.get("day"));
  const selectedDay = trip && Number.isInteger(requestedDay) && requestedDay >= 1 && requestedDay <= dayCount ? requestedDay : trip ? getDefaultTripDay(trip) : 1;
  const steps = publishedSteps.filter((step) => step.day === selectedDay);
  const selectedStep = publishedSteps.find((step) => step.id === searchParams.get("step"));
  const dayRailRef = useRef<HTMLElement>(null);
  const dayButtonRefs = useRef<Array<HTMLButtonElement | null>>([]);

  useEffect(() => {
    dayButtonRefs.current[selectedDay - 1]?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
  }, [selectedDay]);

  if (!tripId) return <Navigate to={preview ? "/dashboard/trips" : "/voyageur/dashboard"} replace />;
  if (isLoading) return <div className="grid min-h-[60vh] place-items-center"><span className="animate-pulse">Chargement du programme…</span></div>;
  if (error || !trip) return <div className="traveler-shell"><div className="traveler-empty" role="alert"><h1 className="text-2xl font-semibold">Voyage inaccessible</h1><p className="mt-2 text-muted-foreground">Ce voyage n’existe pas ou ne vous est pas partagé.</p><Button className="mt-5" onClick={refetchTrips}>Réessayer</Button></div></div>;

  const setDay = (day: number) => { const next = new URLSearchParams(searchParams); next.set("day", String(day)); next.delete("step"); setSearchParams(next); };
  const handleDayKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>, day: number) => { if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return; event.preventDefault(); const nextDay = Math.min(dayCount, Math.max(1, day + (event.key === "ArrowRight" ? 1 : -1))); dayButtonRefs.current[nextDay - 1]?.focus(); setDay(nextDay); };
  const openStep = (step: TripStep) => { const next = new URLSearchParams(searchParams); next.set("day", String(step.day)); next.set("step", step.id); setSearchParams(next); };
  const closeStep = () => { const next = new URLSearchParams(searchParams); next.delete("step"); setSearchParams(next, { replace: true }); };
  const validate = async (step: TripStep, status: "approved" | "rejected") => {
    if (validating) return;
    setValidating(`${step.id}:${status}`);
    try { const persisted = await validateTripStep(trip.id, step.id, status); if (!persisted) throw new Error("Validation non confirmée"); toast.success(status === "approved" ? "Étape confirmée" : "Demande de modification enregistrée"); if (status === "rejected") { closeStep(); setConversation({ step, initialMessage: "Bonjour, je souhaiterais demander une modification concernant cette étape : " }); } }
    catch { toast.error("La réponse n’a pas pu être enregistrée."); }
    finally { setValidating(null); }
  };

  const visibleDocuments = getVisibleDocuments(trip);
  const dayDocuments = visibleDocuments.filter((document) => steps.some((step) => step.id === document.stepId));
  const selectedValidation = selectedStep && currentUser ? getTravelerValidation(selectedStep, currentUser.id) : "pending";
  return <div className="traveler-shell traveler-shell--wide space-y-0">
    {preview && <div className="mb-4 flex flex-col gap-3 rounded-2xl bg-secondary px-5 py-4 text-secondary-foreground sm:flex-row sm:items-center sm:justify-between"><div className="flex items-center gap-3"><Eye className="h-5 w-5 shrink-0" aria-hidden="true" /><div><p className="font-semibold">Aperçu côté voyageur</p><p className="text-sm text-secondary-foreground/70">Seules les étapes publiées sont affichées. Les actions voyageur sont désactivées.</p></div></div><Button asChild variant="outline" className="shrink-0 border-white/30 bg-transparent text-white hover:bg-white hover:text-secondary"><Link to={`/dashboard/trips/${trip.id}/itinerary`}>Retour à l’édition</Link></Button></div>}
    <header className="traveler-hero" style={trip.coverUrl ? { backgroundImage: `linear-gradient(90deg,rgba(12,27,37,.86),rgba(12,27,37,.32)),url(${trip.coverUrl})` } : undefined}>
      <div className="traveler-hero__grain" /><div className="relative z-10 max-w-3xl"><p className="traveler-eyebrow text-white/70">Votre carnet de voyage</p><h1 className="traveler-display mt-4 text-5xl text-white sm:text-6xl lg:text-7xl">{trip.destination}</h1><p className="mt-4 text-lg text-white/80">{trip.title}</p><div className="mt-8 flex flex-wrap items-center gap-x-7 gap-y-3 text-sm text-white/80"><span>{formatDateRange(trip.startDate, trip.endDate)}</span><span className="hidden h-1 w-1 rounded-full bg-white/50 sm:block" /><span>{dayCount} jour{dayCount > 1 ? "s" : ""} d’évasion</span></div></div><ArrowDown className="absolute bottom-7 right-7 h-5 w-5 text-white/70" aria-hidden="true" />
    </header>
    <div className="sticky top-16 z-20 -mx-4 border-b border-black/5 bg-[#f7f4ed]/95 px-4 backdrop-blur-xl sm:-mx-6 sm:px-6 lg:top-[72px] lg:-mx-8 lg:px-8"><nav ref={dayRailRef} aria-label="Jours du voyage" className="traveler-day-rail mx-auto flex max-w-5xl gap-7 overflow-x-auto whitespace-nowrap py-1 sm:gap-10">{Array.from({ length: dayCount }, (_, index) => index + 1).map((day) => <button ref={(node) => { dayButtonRefs.current[day - 1] = node; }} key={day} onClick={() => setDay(day)} onKeyDown={(event) => handleDayKeyDown(event, day)} aria-current={selectedDay === day ? "date" : undefined} className={`relative min-w-max shrink-0 snap-center px-1 py-5 text-left transition ${selectedDay === day ? "text-[#d85f4c]" : "text-slate-500 hover:text-slate-900"}`}><span className="block whitespace-nowrap text-[10px] font-bold uppercase tracking-[.2em]">Jour {day}</span><span className="mt-1 block whitespace-nowrap text-sm font-semibold capitalize">{getTripDayLabel(trip, day)}</span><span className={`absolute inset-x-0 bottom-0 h-0.5 bg-[#d85f4c] ${selectedDay === day ? "scale-x-100" : "scale-x-0"}`} /></button>)}</nav></div>
    <main className="mx-auto w-full max-w-5xl py-10 sm:py-14">
      <div className="mb-9 flex items-end justify-between gap-4"><div><p className="traveler-eyebrow text-[#d85f4c]">Jour {String(selectedDay).padStart(2, "0")}</p><h2 className="traveler-display mt-2 text-4xl text-slate-900 sm:text-5xl">Le programme</h2></div><div className="flex gap-1"><button aria-label="Jour précédent" className="traveler-icon-button" disabled={selectedDay <= 1} onClick={() => setDay(selectedDay - 1)}><ChevronLeft /></button><button aria-label="Jour suivant" className="traveler-icon-button" disabled={selectedDay >= dayCount} onClick={() => setDay(selectedDay + 1)}><ChevronRight /></button></div></div>
      <section aria-label={`Programme du jour ${selectedDay}`} className="traveler-timeline">{steps.length ? steps.map((step, index) => { const status = !preview && currentUser ? getTravelerValidation(step, currentUser.id) : "pending"; return <button key={step.id} onClick={() => openStep(step)} className="traveler-step group"><div className="traveler-step__time"><span>{step.startTime || step.time || "—"}</span>{step.endTime && <small>{step.endTime}</small>}</div><span className="traveler-step__marker"><span>{String(index + 1).padStart(2, "0")}</span></span><div className="traveler-step__content"><div className="flex items-start gap-3 sm:gap-4">{step.imagePath && <StepImageThumbnail step={step} />}<div className="min-w-0 flex-1"><div className="flex flex-wrap items-start justify-between gap-3"><div><p className="text-[10px] font-bold uppercase tracking-[.18em] text-[#d85f4c]">{step.stepType || "Découverte"}</p><h3 className="mt-1 text-xl font-semibold text-slate-900 sm:text-2xl">{step.activity}</h3></div>{status !== "pending" && <span className={`traveler-status ${status === "approved" ? "traveler-status--approved" : "traveler-status--review"}`}>{status === "approved" ? <Check /> : <MessageCircle />}{status === "approved" ? "Confirmée" : "À revoir"}</span>}</div>{step.location && <p className="mt-3 flex items-center gap-2 text-sm text-slate-500"><MapPin className="h-4 w-4 text-[#d85f4c]" />{step.location}</p>}{step.description && <p className="mt-4 line-clamp-2 max-w-2xl text-sm leading-7 text-slate-600">{step.description}</p>}<span className="mt-5 inline-flex items-center gap-2 text-xs font-bold uppercase tracking-[.12em] text-slate-800">Découvrir l’étape <ChevronRight className="h-4 w-4 transition-transform group-hover:translate-x-1" /></span></div></div></div></button>; }) : <div className="traveler-empty"><p className="traveler-eyebrow text-[#d85f4c]">Un peu de patience</p><h3 className="traveler-display mt-2 text-3xl">La suite s’écrit bientôt</h3><p className="mt-3 text-sm text-muted-foreground">Votre Travel Planner n’a pas encore publié d’étape pour cette journée.</p></div>}</section>
      <div className="mt-14 flex flex-col gap-4 border-t border-slate-900/10 pt-7 sm:flex-row sm:items-center sm:justify-between"><div><p className="font-semibold">Documents de la journée</p><p className="mt-1 text-sm text-slate-500">{dayDocuments.length ? `${dayDocuments.length} document${dayDocuments.length > 1 ? "s" : ""} lié${dayDocuments.length > 1 ? "s" : ""} à ce programme` : "Tous vos essentiels de voyage au même endroit"}</p></div><Button asChild variant="ghost" className="justify-start px-0 text-[#d85f4c] hover:bg-transparent hover:text-[#b94c3c]"><Link to={preview ? `/dashboard/trips/${trip.id}/documents` : `/voyageur/documents/${trip.id}`}><FileText className="mr-2 h-4 w-4" />Voir tous les documents <ChevronRight className="ml-1 h-4 w-4" /></Link></Button></div>
    </main>
    <Dialog open={Boolean(selectedStep)} onOpenChange={(open) => !open && closeStep()}><DialogContent className="traveler-step-dialog max-h-[92vh] overflow-y-auto border-0 p-0 sm:max-w-xl">{selectedStep && <>
      {selectedStep.imagePath && <StepImage step={selectedStep} />}
      <div className="p-6 sm:p-9"><DialogHeader><p className="traveler-eyebrow text-[#d85f4c]">Jour {selectedStep.day} · {selectedStep.startTime || selectedStep.time}{selectedStep.endTime ? ` — ${selectedStep.endTime}` : ""}</p><DialogTitle className="traveler-display mt-2 text-left text-4xl leading-tight">{selectedStep.activity}</DialogTitle><DialogDescription className="sr-only">Détail de l’étape {selectedStep.activity}</DialogDescription></DialogHeader>
        <div className="mt-6 space-y-7"><div>{selectedStep.location?.trim() && <p className="flex items-start gap-3 font-medium text-slate-800"><MapPin className="mt-0.5 h-5 w-5 text-[#d85f4c]" aria-hidden="true" />{selectedStep.location}</p>}{selectedStep.description && <p className="mt-5 whitespace-pre-wrap text-[15px] leading-7 text-slate-600">{selectedStep.description}</p>}</div>
          {(selectedStep.estimatedDuration || selectedStep.activityType || selectedStep.guideName || selectedStep.walkingLevel) && <dl className="grid gap-3 rounded-2xl bg-slate-900/[.04] p-5 text-sm sm:grid-cols-2">{selectedStep.estimatedDuration && <div><dt className="text-slate-500">Durée</dt><dd className="mt-1 font-medium text-slate-800">{selectedStep.estimatedDuration}</dd></div>}{selectedStep.activityType && <div><dt className="text-slate-500">Type</dt><dd className="mt-1 font-medium text-slate-800">{selectedStep.activityType}</dd></div>}{selectedStep.guideName && <div><dt className="text-slate-500">Guide / contact</dt><dd className="mt-1 font-medium text-slate-800">{selectedStep.guideName}</dd></div>}{selectedStep.walkingLevel && <div><dt className="text-slate-500">Accessibilité</dt><dd className="mt-1 font-medium text-slate-800">{selectedStep.walkingLevel}</dd></div>}</dl>}
          {(selectedStep.location?.trim() || selectedStep.link || selectedStep.links?.length) && <div className="flex flex-wrap gap-x-5 gap-y-3">{selectedStep.location?.trim() && <a href={buildMapsUrl(selectedStep.location)} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-[.13em] text-[#d85f4c]">Voir sur la carte <ExternalLink className="h-4 w-4" aria-hidden="true" /></a>}{selectedStep.link && <a href={selectedStep.link} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-[.13em] text-[#d85f4c]">Lien utile <ExternalLink className="h-4 w-4" /></a>}{selectedStep.links?.map((link) => <a key={`${link.url}-${link.title}`} href={link.url} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-2 text-xs font-bold uppercase tracking-[.13em] text-[#d85f4c]">{link.title || "Lien utile"}<ExternalLink className="h-4 w-4" /></a>)}</div>}
          {visibleDocuments.filter((document) => document.stepId === selectedStep.id).length > 0 && <section className="border-t border-slate-900/10 pt-6"><h3 className="mb-3 text-sm font-semibold">Documents utiles</h3>{visibleDocuments.filter((document) => document.stepId === selectedStep.id).map((document) => <DocumentItem key={document.id} document={document} tripId={trip.id} isPlanner={false} />)}</section>}
          {!preview && <><div className="grid gap-3 border-t border-slate-900/10 pt-6 sm:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)]">{selectedValidation === "approved" ? <div className="inline-flex h-12 w-full min-w-0 cursor-default items-center justify-center gap-2 rounded-full bg-emerald-800/10 px-6 text-center text-sm font-semibold leading-none text-emerald-800"><Check className="h-4 w-4 shrink-0" aria-hidden="true" /><span>Étape validée</span></div> : <Button disabled={Boolean(validating)} onClick={() => validate(selectedStep, "approved")} className="inline-flex h-12 w-full min-w-0 items-center justify-center gap-2 rounded-full px-6 text-sm leading-none"><Check className="h-4 w-4 shrink-0" aria-hidden="true" /><span>Ça me convient</span></Button>}<Button disabled={Boolean(validating)} variant="outline" onClick={() => validate(selectedStep, "rejected")} className="inline-flex h-12 w-full min-w-0 items-center justify-center gap-2 rounded-full px-6 text-sm leading-none"><X className="h-4 w-4 shrink-0" aria-hidden="true" /><span>Demander une modification</span></Button></div>
          <Button variant="ghost" className="w-full rounded-full" onClick={() => { closeStep(); setConversation({ step: selectedStep }); }}><MessageCircle className="mr-2 h-4 w-4" />Commentaires ({selectedStep.comments.length})</Button></>}
        </div>
      </div>
    </>}</DialogContent></Dialog>
    {conversation && <StepComments isOpen onClose={() => setConversation(null)} tripId={trip.id} step={conversation.step} initialMessage={conversation.initialMessage} />}
  </div>;
}
