import { useEffect } from "react";
import { Link } from "react-router-dom";
import { AlertCircle, ArrowRight, CalendarDays, Clock3, FileText, MapPin, MessageCircle, RefreshCw, Sparkles } from "lucide-react";
import { differenceInCalendarDays, format, formatDistanceToNow, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import { toast } from "sonner";
import { useTrips } from "@/contexts/TripContext";
import { useAuth } from "@/contexts/AuthContext";
import { Button } from "@/components/ui/button";
import { StepImageThumbnail } from "@/components/dashboard/step/StepImage";
import { OnboardingGuide } from "@/components/dashboard/OnboardingGuide";
import { deriveTravelerActivity, type TravelerActivityItem } from "@/services/travelerActivity";
import { getPublishedSteps, getTodayTripDay, getTravelerValidation, getVisibleDocuments, sortTravelerTrips } from "@/services/travelerViewModel";
import type { Trip, TripStep } from "@/types";

const fullDate = (date: Date) => format(date, "EEEE d MMMM", { locale: fr });
const tripDateRange = (trip: Trip) => `${format(parseISO(trip.startDate), "d", { locale: fr })} — ${format(parseISO(trip.endDate), "d MMMM yyyy", { locale: fr })}`;
const tripCover = (trip: Trip) => trip.bannerUrl || trip.coverUrl;
const validationLabel = { approved: "Étape validée", rejected: "Modification demandée", pending: "À valider" } as const;

function TodayStep({ trip, step, travelerId, day }: { trip: Trip; step: TripStep; travelerId: string; day: number }) {
  const validation = getTravelerValidation(step, travelerId);
  const documentCount = getVisibleDocuments(trip).filter((document) => document.stepId === step.id).length;
  return <li className="py-5"><Link to={`/voyageur/trips/${trip.id}?day=${day}&step=${encodeURIComponent(step.id)}`} className="group flex min-h-24 items-center gap-4 rounded-2xl px-1 py-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#d85f4c]"><time className="w-12 shrink-0 self-start pt-1 font-semibold text-slate-800">{step.startTime || step.time || "—"}</time><StepImageThumbnail step={step} /><span className="min-w-0 flex-1"><span className="block font-semibold text-slate-900">{step.activity}</span>{step.location && <span className="mt-1 flex items-center gap-1 text-sm text-slate-500"><MapPin className="h-3.5 w-3.5 shrink-0" aria-hidden="true" />{step.location}</span>}<span className="mt-2 flex flex-wrap gap-x-3 gap-y-1 text-xs text-slate-500">{step.estimatedDuration && <span className="inline-flex items-center gap-1"><Clock3 className="h-3.5 w-3.5" aria-hidden="true" />{step.estimatedDuration}</span>}<span>{validationLabel[validation]}</span>{documentCount > 0 && <span>{documentCount} document{documentCount > 1 ? "s" : ""}</span>}</span></span><span className="hidden shrink-0 items-center gap-1 text-sm font-semibold text-[#d85f4c] sm:inline-flex">Voir le détail<ArrowRight className="h-4 w-4 transition group-hover:translate-x-1" /></span></Link></li>;
}

function TodayTrip({ trip, travelerId, now }: { trip: Trip; travelerId: string; now: Date }) {
  const day = getTodayTripDay(trip, now)!;
  const steps = getPublishedSteps(trip).filter((step) => step.day === day).sort((a, b) => (a.startTime || a.time).localeCompare(b.startTime || b.time));
  const cover = tripCover(trip);
  return <section aria-labelledby={`today-${trip.id}`} className="border-t border-slate-900/10 pt-7"><p className="traveler-eyebrow text-[#d85f4c]">Aujourd’hui</p><div className="mt-3 flex flex-col gap-4 sm:flex-row sm:items-center">{cover && <img src={cover} alt="" className="aspect-[16/9] w-full rounded-2xl object-cover sm:w-32" />}<div className="min-w-0 flex-1"><h2 id={`today-${trip.id}`} className="traveler-display text-3xl text-slate-900">{trip.title}</h2><p className="mt-1 text-slate-500">{trip.destination}</p></div><Button variant="ghost" className="w-fit px-0 text-[#d85f4c]" asChild><Link to={`/voyageur/trips/${trip.id}?day=${day}`}>Voir le voyage<ArrowRight className="ml-2 h-4 w-4" /></Link></Button></div>{steps.length ? <ol className="mt-5 divide-y border-y border-slate-900/10">{steps.map((step) => <TodayStep key={step.id} trip={trip} step={step} travelerId={travelerId} day={day} />)}</ol> : <div className="mt-6 py-6"><h3 className="traveler-display text-2xl text-slate-900">Rien de prévu aujourd’hui</h3><p className="mt-2 text-slate-500">Profitez de votre journée libre.</p><Button variant="outline" className="mt-5" asChild><Link to={`/voyageur/trips/${trip.id}`}>Voir le programme du voyage</Link></Button></div>}</section>;
}

function ActivityIcon({ kind }: { kind: TravelerActivityItem["kind"] }) { const Icon = kind === "comment" ? MessageCircle : kind === "document" ? FileText : Sparkles; return <Icon className="h-4 w-4" aria-hidden="true" />; }
function RecentActivity({ events, error }: { events: TravelerActivityItem[]; error: string | null }) { return <section aria-labelledby="recent-activity" className="border-t border-slate-900/10 pt-8"><p className="traveler-eyebrow text-slate-500">Activité récente</p><h2 id="recent-activity" className="traveler-display mt-2 text-3xl text-slate-900">Les nouveautés de vos voyages</h2>{error ? <p className="mt-4 text-sm text-slate-500">Impossible de charger l’activité récente.</p> : events.length ? <ol className="mt-5 divide-y border-y border-slate-900/10">{events.slice(0, 6).map((event) => <li key={event.id}><Link to={event.href} className="group flex min-h-20 items-center gap-4 py-4"><span className="grid h-9 w-9 shrink-0 place-items-center rounded-full bg-white/70 text-[#d85f4c]"><ActivityIcon kind={event.kind} /></span><span className="min-w-0 flex-1"><span className="block font-semibold text-slate-900">{event.title}</span><span className="mt-1 block text-sm text-slate-500">{event.detail} · {formatDistanceToNow(parseISO(event.at), { addSuffix: true, locale: fr })}</span></span><span className="shrink-0 text-sm font-semibold text-[#d85f4c]">{event.action}</span></Link></li>)}</ol> : <p className="mt-4 text-slate-500">Vous n’avez aucune activité récente pour le moment.</p>}</section>; }

export default function TravelerDashboard() {
  const { getUserTrips, isLoading, error, activityError, refetchTrips } = useTrips(); const { currentUser } = useAuth();
  const trips = getUserTrips(); const today = new Date(); const grouped = sortTravelerTrips(trips, today); const activity = deriveTravelerActivity(trips);
  useEffect(() => { if (localStorage.getItem("firstLogin") === "true" && currentUser) { toast.success("Bienvenue dans votre espace de voyage !"); localStorage.removeItem("firstLogin"); } }, [currentUser]);
  if (isLoading || !currentUser) return <div className="grid min-h-[60vh] place-items-center" aria-live="polite"><span className="animate-pulse">Chargement de votre journée…</span></div>;
  if (error) return <div className="page-shell"><div className="surface-card mx-auto max-w-xl p-8 text-center" role="alert"><AlertCircle className="mx-auto text-destructive" /><h1 className="mt-3 text-xl font-semibold">Impossible de charger votre journée</h1><Button className="mt-5" onClick={refetchTrips}><RefreshCw className="mr-2 h-4 w-4" />Réessayer</Button></div></div>;
  const upcoming = grouped.upcoming[0]; const lastTrip = grouped.past[0];
  return <div className="traveler-shell space-y-10"><header className="py-5 sm:py-9"><p className="text-lg text-slate-600">Bonjour {currentUser.name}</p><h1 className="traveler-display mt-2 text-5xl capitalize text-slate-900 sm:text-6xl">{fullDate(today)}</h1><p className="traveler-eyebrow mt-5 text-[#d85f4c]">Aujourd’hui</p></header>
    <OnboardingGuide role="traveler" hasTrips={trips.length > 0} />
    {grouped.current.length > 0 ? <div className="space-y-10">{grouped.current.map((trip) => <TodayTrip key={trip.id} trip={trip} travelerId={currentUser.id} now={today} />)}</div> : upcoming ? <section className="overflow-hidden rounded-[2rem] bg-white/65"><div className="grid sm:grid-cols-[minmax(0,.9fr)_minmax(0,1.1fr)] sm:items-stretch">{tripCover(upcoming) && <div className="aspect-[16/9] overflow-hidden sm:aspect-auto sm:min-h-full"><img src={tripCover(upcoming)} alt={`Vue de ${upcoming.destination}`} className="h-full w-full object-cover" /></div>}<div className="p-6 sm:p-8"><CalendarDays className="h-6 w-6 text-[#d85f4c]" /><p className="traveler-eyebrow mt-5 text-[#d85f4c]">Votre voyage approche</p><h2 className="traveler-display mt-2 text-3xl text-slate-900">{upcoming.title}</h2><p className="mt-1 text-slate-500">{upcoming.destination}</p><p className="mt-4 text-sm text-slate-600">{tripDateRange(upcoming)}</p><p className="mt-1 font-semibold text-slate-800">Départ dans {differenceInCalendarDays(parseISO(upcoming.startDate), today)} jours</p><Button variant="outline" className="mt-6 w-full sm:w-auto" asChild><Link to={`/voyageur/trips/${upcoming.id}`}>Voir le voyage<ArrowRight className="ml-2 h-4 w-4" /></Link></Button></div></div></section> : lastTrip ? <section className="border-t border-slate-900/10 py-8"><h2 className="traveler-display text-3xl text-slate-900">Votre voyage est terminé</h2><p className="mt-3 text-slate-500">Vous pouvez toujours retrouver votre programme et vos documents.</p><Button variant="outline" className="mt-6" asChild><Link to={`/voyageur/trips/${lastTrip.id}`}>Revoir le voyage</Link></Button></section> : <section className="border-t border-slate-900/10 py-8"><h2 className="text-xl font-semibold">Aucun voyage ne vous a encore été partagé</h2><p className="mt-2 text-slate-500">Votre programme apparaîtra ici dès qu’un voyage sera partagé.</p></section>}
    {trips.length > 0 && <RecentActivity events={activity} error={activityError} />}
    {grouped.current.length === 0 && grouped.past.length > 0 && upcoming && <section className="border-t border-slate-900/10 pt-8"><p className="traveler-eyebrow text-slate-500">Voyages passés</p><Button variant="ghost" className="mt-2 px-0" asChild><Link to={`/voyageur/trips/${grouped.past[0].id}`}>{grouped.past[0].title}<ArrowRight className="ml-2 h-4 w-4" /></Link></Button></section>}
  </div>;
}
