import { useEffect, useMemo, useRef, useState } from "react";
import { ArrowLeft, ArrowRight, Check, CalendarDays, Loader2, MapPin, Plus, Search, UserPlus, Users } from "lucide-react";
import { useNavigate } from "react-router-dom";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useTrips } from "@/contexts/TripContext";
import { useTravelerSearch } from "@/hooks/useTravelerSearch";
import { inviteTraveler } from "@/services/invitationService";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Progress } from "@/components/ui/progress";

type Participant = { key: string; type: "existing" | "new"; id?: string; name: string; email: string };
type CreatedResult = { id: string; title: string; failedInvitations: string[]; participantCount: number };
interface Props { onCancel?: () => void; }

const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const generatedTitle = (destination: string) => `Voyage ${/^[aeiouyàâäéèêëîïôöùûü]/i.test(destination.trim()) ? "en" : "au"} ${destination.trim()}`;

export function TripCreationFlow({ onCancel }: Props) {
  const { currentUser } = useAuth();
  const { createTrip, refetchTrips } = useTrips();
  const { travelers, searchTerm, setSearchTerm, loading: travelersLoading } = useTravelerSearch();
  const navigate = useNavigate();
  const [step, setStep] = useState(1);
  const [destination, setDestination] = useState("");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [participants, setParticipants] = useState<Participant[]>([]);
  const [newName, setNewName] = useState("");
  const [newEmail, setNewEmail] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [creating, setCreating] = useState(false);
  const [result, setResult] = useState<CreatedResult | null>(null);
  const submittingRef = useRef(false);
  const headingRef = useRef<HTMLHeadingElement>(null);

  useEffect(() => { headingRef.current?.focus(); }, [step, result]);
  const title = generatedTitle(destination);
  const selectedEmails = useMemo(() => new Set(participants.map((participant) => participant.email.toLowerCase())), [participants]);
  const addExisting = (traveler: typeof travelers[number]) => {
    if (selectedEmails.has(traveler.email.toLowerCase())) return;
    setParticipants((current) => [...current, { key: traveler.id || traveler.email, type: traveler.id ? "existing" : "new", id: traveler.id || undefined, name: traveler.name, email: traveler.email }]);
  };
  const addNew = () => {
    const name = newName.trim(); const email = newEmail.trim().toLowerCase();
    if (name.length < 2) return setError("Indiquez le nom du voyageur.");
    if (!emailPattern.test(email)) return setError("Indiquez une adresse email valide.");
    if (selectedEmails.has(email)) return setError("Cette personne participe déjà au voyage.");
    setParticipants((current) => [...current, { key: email, type: "new", name, email }]); setNewName(""); setNewEmail(""); setError(null);
  };
  const continueFlow = () => {
    setError(null);
    if (step === 1 && destination.trim().length < 2) return setError("Indiquez une destination pour continuer.");
    if (step === 2 && !startDate) return setError("Sélectionnez une date de début.");
    if (step === 2 && !endDate) return setError("Sélectionnez une date de fin.");
    if (step === 2 && endDate < startDate) return setError("La date de fin doit être postérieure ou égale à la date de début.");
    setStep((current) => Math.min(4, current + 1));
  };
  const create = async () => {
    if (submittingRef.current || !currentUser) return;
    submittingRef.current = true; setCreating(true); setError(null);
    try {
      const trip = await createTrip({ title, destination: destination.trim(), startDate, endDate, plannerId: currentUser.id, travelerId: "", travelerEmail: "", travelerName: "" });
      if (!trip) throw new Error("Création non confirmée");
      const failedInvitations: string[] = [];
      for (const participant of participants) {
        try {
          if (participant.type === "existing" && participant.id) {
            const { error: assignmentError } = await supabase.rpc("assign_existing_traveler", { p_trip_id: trip.id, p_traveler_id: participant.id });
            if (assignmentError) throw assignmentError;
          } else {
            await inviteTraveler({ tripId: trip.id, email: participant.email, travelerName: participant.name });
          }
        } catch (participantError) { console.error("Initial traveler association failed", { tripId: trip.id, email: participant.email, participantError }); failedInvitations.push(participant.email); }
      }
      refetchTrips(); setResult({ id: trip.id, title: trip.title, failedInvitations, participantCount: participants.length });
    } catch (creationError) { console.error("Trip creation failed", creationError); setError("Impossible de créer ce voyage. Vos informations sont conservées."); }
    finally { submittingRef.current = false; setCreating(false); }
  };

  if (result) return <section className="mx-auto max-w-xl py-8 text-center"><span className="mx-auto grid h-14 w-14 place-items-center rounded-full bg-emerald-100 text-emerald-700"><Check className="h-7 w-7" /></span><h1 ref={headingRef} tabIndex={-1} className="mt-5 text-3xl font-bold outline-none">Votre voyage est prêt</h1><p className="mt-2 text-muted-foreground">{result.title} · {startDate} → {endDate}</p><p className="mt-1 text-sm text-muted-foreground">{result.participantCount ? `${result.participantCount} participant(s) traité(s)` : "Vous pourrez ajouter des voyageurs plus tard."}</p>{result.failedInvitations.length > 0 && <div role="alert" className="mt-5 rounded-xl border border-amber-300 bg-amber-50 p-4 text-left text-sm"><strong>Le voyage est bien créé.</strong><p className="mt-1">Invitation ou association à reprendre depuis Voyageurs : {result.failedInvitations.join(", ")}.</p></div>}<div className="mt-7 grid gap-3 sm:grid-cols-2"><Button size="lg" onClick={() => navigate(`/dashboard/trips/${result.id}/itinerary`)}>Commencer l’itinéraire <ArrowRight className="ml-2 h-4 w-4" /></Button><Button size="lg" variant="outline" onClick={() => navigate(`/dashboard/trips/${result.id}`)}>Voir le voyage</Button></div></section>;

  return <section className="mx-auto max-w-2xl"><div className="mb-8"><div className="flex items-center justify-between text-xs font-semibold text-muted-foreground"><span>{step} sur 4</span><span>{step === 1 ? "Destination" : step === 2 ? "Dates" : step === 3 ? "Voyageurs" : "Démarrage"}</span></div><Progress value={step * 25} className="mt-2 h-1.5" /></div>
    <div className="min-h-[330px]">{step === 1 && <div><MapPin className="h-7 w-7 text-primary" /><h1 ref={headingRef} tabIndex={-1} className="mt-4 text-3xl font-bold outline-none">Où partent vos voyageurs ?</h1><p className="mt-2 text-muted-foreground">Une destination suffit pour commencer.</p><label className="mt-8 block text-sm font-semibold" htmlFor="creation-destination">Destination</label><Input id="creation-destination" autoFocus value={destination} onChange={(event) => { setDestination(event.target.value); setError(null); }} className="mt-2 h-14 text-lg" placeholder="Japon" /><p className="mt-3 text-sm text-muted-foreground">Titre proposé : <strong className="text-foreground">{destination.trim() ? title : "Voyage au Japon"}</strong></p></div>}
      {step === 2 && <div><CalendarDays className="h-7 w-7 text-primary" /><h1 ref={headingRef} tabIndex={-1} className="mt-4 text-3xl font-bold outline-none">Quand a lieu le voyage ?</h1><p className="mt-2 text-muted-foreground">Les journées de l’itinéraire seront créées automatiquement.</p><div className="mt-8 grid gap-5 sm:grid-cols-2"><label className="text-sm font-semibold">Date de début<Input type="date" value={startDate} onChange={(event) => { const value = event.target.value; setStartDate(value); if (endDate && endDate < value) setEndDate(value); setError(null); }} className="mt-2 h-12" /></label><label className="text-sm font-semibold">Date de fin<Input type="date" min={startDate || undefined} value={endDate} onChange={(event) => { setEndDate(event.target.value); setError(null); }} className="mt-2 h-12" /></label></div></div>}
      {step === 3 && <div><Users className="h-7 w-7 text-primary" /><h1 ref={headingRef} tabIndex={-1} className="mt-4 text-3xl font-bold outline-none">Qui participe à ce voyage ?</h1><p className="mt-2 text-muted-foreground">Cette étape est facultative. Vous pourrez inviter d’autres personnes plus tard.</p><div className="mt-6 rounded-2xl border p-4"><label className="relative block"><span className="sr-only">Rechercher un client existant</span><Search className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" /><Input value={searchTerm} onChange={(event) => setSearchTerm(event.target.value)} className="pl-9" placeholder="Rechercher un client…" /></label><div className="mt-3 max-h-36 space-y-1 overflow-y-auto">{travelersLoading ? <p className="p-2 text-sm text-muted-foreground">Chargement…</p> : travelers.map((traveler) => <button key={traveler.id || traveler.email} type="button" disabled={selectedEmails.has(traveler.email.toLowerCase())} onClick={() => addExisting(traveler)} className="flex w-full items-center justify-between rounded-lg p-2 text-left hover:bg-muted disabled:opacity-50"><span><strong className="block text-sm">{traveler.name}</strong><span className="text-xs text-muted-foreground">{traveler.email}</span></span><Plus className="h-4 w-4" /></button>)}</div></div><div className="mt-4 rounded-2xl bg-muted/45 p-4"><p className="flex items-center gap-2 font-semibold"><UserPlus className="h-4 w-4" />Ajouter un nouveau voyageur</p><div className="mt-3 grid gap-2 sm:grid-cols-[1fr_1.2fr_auto]"><Input aria-label="Nom du nouveau voyageur" value={newName} onChange={(event) => setNewName(event.target.value)} placeholder="Nom" /><Input aria-label="Email du nouveau voyageur" type="email" value={newEmail} onChange={(event) => setNewEmail(event.target.value)} placeholder="email@exemple.fr" /><Button type="button" variant="outline" onClick={addNew}>Ajouter</Button></div></div>{participants.length > 0 && <ul className="mt-4 flex flex-wrap gap-2">{participants.map((participant) => <li key={participant.key} className="flex items-center gap-2 rounded-full bg-primary/10 px-3 py-2 text-sm"><Check className="h-3.5 w-3.5 text-primary" />{participant.name}<button type="button" onClick={() => setParticipants((current) => current.filter((item) => item.key !== participant.key))} aria-label={`Retirer ${participant.name}`}>×</button></li>)}</ul>}</div>}
      {step === 4 && <div><Check className="h-7 w-7 text-primary" /><h1 ref={headingRef} tabIndex={-1} className="mt-4 text-3xl font-bold outline-none">Comment souhaitez-vous commencer ?</h1><p className="mt-2 text-muted-foreground">Votre voyage sera créé uniquement lorsque vous confirmerez.</p><button type="button" className="mt-8 flex w-full items-start gap-4 rounded-2xl border-2 border-primary bg-primary/5 p-5 text-left"><span className="grid h-10 w-10 place-items-center rounded-full bg-primary text-primary-foreground"><Check /></span><span><strong className="text-lg">Partir de zéro</strong><span className="mt-1 block text-sm text-muted-foreground">Commencer avec un itinéraire vide et ajouter les étapes à votre rythme.</span></span></button></div>}</div>
    {error && <p className="mt-4 rounded-lg bg-destructive/10 p-3 text-sm text-destructive" role="alert">{error}</p>}<footer className="mt-8 flex items-center justify-between border-t pt-5"><div>{step > 1 ? <Button type="button" variant="ghost" onClick={() => { setStep((current) => current - 1); setError(null); }}><ArrowLeft className="mr-2 h-4 w-4" />Précédent</Button> : onCancel ? <Button type="button" variant="ghost" onClick={onCancel}>Annuler</Button> : null}</div>{step < 4 ? <Button type="button" onClick={continueFlow}>Continuer <ArrowRight className="ml-2 h-4 w-4" /></Button> : <Button type="button" onClick={() => void create()} disabled={creating}>{creating ? <><Loader2 className="mr-2 h-4 w-4 animate-spin" />Création…</> : "Créer le voyage"}</Button>}</footer>
  </section>;
}
