import { useEffect, useRef, useState } from "react";
import { Loader2, Send } from "lucide-react";
import { useTrips } from "@/contexts/TripContext";
import { useSupabaseComments } from "@/hooks/useSupabaseComments";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { COMMENT_MAX_LENGTH, normalizeCommentContent } from "@/services/commentGuards";
import { formatCommunicationTime, getCommentRole } from "@/services/communication";
import type { Comment, TripStep } from "@/types";

interface Props { tripId: string; plannerId: string; step: TripStep; initialMessage?: string; onSent?: () => void; }
const initials = (name: string) => name.split(" ").filter(Boolean).map((part) => part[0]).join("").slice(0, 2).toUpperCase() || "?";

export function StepConversation({ tripId, plannerId, step, initialMessage = "", onSent }: Props) {
  const { addStepComment } = useTrips();
  const { getStepComments } = useSupabaseComments();
  const [comments, setComments] = useState<Comment[]>(step.comments || []);
  const [message, setMessage] = useState(initialMessage);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState(false);
  const [retry, setRetry] = useState(0);
  const [sending, setSending] = useState(false);
  const [feedback, setFeedback] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const sendingRef = useRef(false);

  useEffect(() => {
    let active = true;
    let timeoutId: ReturnType<typeof setTimeout>;
    setLoading(true); setLoadError(false); setFeedback(null); setMessage(initialMessage);
    const timeout = new Promise<Comment[]>((_, reject) => { timeoutId = setTimeout(() => reject(new Error("Conversation timeout")), 15000); });
    Promise.race([getStepComments(step.id), timeout]).then((fresh) => { if (active) setComments(fresh); }).catch(() => { if (active) setLoadError(true); }).finally(() => { clearTimeout(timeoutId); if (active) setLoading(false); });
    return () => { active = false; clearTimeout(timeoutId); };
  }, [getStepComments, initialMessage, retry, step.id]);

  const send = async () => {
    if (sendingRef.current) return;
    let content: string;
    try { content = normalizeCommentContent(message); } catch (error) { setFeedback({ type: "error", text: error instanceof Error ? error.message : "Message invalide." }); return; }
    sendingRef.current = true; setSending(true); setFeedback(null);
    try {
      const added = await addStepComment(tripId, step.id, { content });
      if (!added) throw new Error("Envoi non confirmé");
      setComments((current) => current.some((comment) => comment.id === added.id) ? current : [...current, added]);
      setMessage(""); setFeedback({ type: "success", text: "Message envoyé" }); onSent?.();
    } catch { setFeedback({ type: "error", text: "Le message n’a pas pu être envoyé. Votre texte est conservé, vous pouvez réessayer." }); }
    finally { sendingRef.current = false; setSending(false); }
  };

  return <div className="flex min-h-0 flex-col">
    <div className="max-h-[48vh] min-h-48 space-y-4 overflow-y-auto py-3" aria-live="polite">{loading ? <div className="grid min-h-40 place-items-center"><Loader2 className="h-5 w-5 animate-spin" aria-label="Chargement des messages" /></div> : loadError ? <div className="grid min-h-40 place-items-center text-center"><div><p role="alert" className="text-sm font-medium">Impossible de charger la conversation.</p><Button className="mt-3" size="sm" variant="outline" onClick={() => setRetry((value) => value + 1)}>Réessayer</Button></div></div> : comments.length ? comments.map((comment) => <article key={comment.id} className="flex gap-3"><Avatar className="h-9 w-9"><AvatarFallback>{initials(comment.userName)}</AvatarFallback></Avatar><div className="min-w-0 flex-1 rounded-2xl bg-muted/55 px-4 py-3"><div className="flex flex-wrap items-baseline justify-between gap-2"><p className="text-sm font-semibold">{comment.userName} <span className="font-normal text-muted-foreground">· {getCommentRole(comment, plannerId)}</span></p><time className="text-xs text-muted-foreground" dateTime={comment.createdAt}>{formatCommunicationTime(comment.createdAt)}</time></div><p className="mt-1 whitespace-pre-wrap break-words text-sm">{comment.content}</p></div></article>) : <div className="grid min-h-40 place-items-center text-center text-sm text-muted-foreground">Aucun message sur cette étape.</div>}</div>
    <div className="border-t pt-4"><label htmlFor={`message-${step.id}`} className="text-sm font-semibold">Votre message</label><Textarea id={`message-${step.id}`} autoFocus value={message} onChange={(event) => { setMessage(event.target.value); if (feedback?.type === "success") setFeedback(null); }} maxLength={COMMENT_MAX_LENGTH} className="mt-2 min-h-24" placeholder="Écrivez un message lié à cette étape…" disabled={sending} /><div className="mt-2 flex items-start justify-between gap-3"><div>{feedback && <p role={feedback.type === "error" ? "alert" : "status"} className={`text-sm ${feedback.type === "error" ? "text-destructive" : "text-emerald-700"}`}>{feedback.text}</p>}<p className="text-xs text-muted-foreground">{message.length}/{COMMENT_MAX_LENGTH}</p></div><Button onClick={() => void send()} disabled={!message.trim() || sending}>{sending ? <><Loader2 className="mr-2 h-4 w-4 animate-spin" />Envoi…</> : <><Send className="mr-2 h-4 w-4" />Envoyer</>}</Button></div></div>
  </div>;
}
