"use client";

import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { Loader2, MessageCircle, Send, Star, Wifi, WifiOff } from "lucide-react";
import { cn } from "@/lib/utils";

type ChatMessage = {
  id: string;
  senderRole: "USER" | "ADMIN" | "SYSTEM";
  body: string;
  createdAt: string;
};

type Conversation = {
  id: string;
  status: string;
  rating: number | null;
  ratingComment: string | null;
  ratingRequestedAt: string | null;
  messages: ChatMessage[];
};

type Availability = {
  liveChatOnline: boolean;
  message: string;
  supportHours: string;
  ticketResponseTime: string;
};

export function SupportLiveChatClient() {
  const [availability, setAvailability] = useState<Availability | null>(null);
  const [conversation, setConversation] = useState<Conversation | null>(null);
  const [draft, setDraft] = useState("");
  const [initialMessage, setInitialMessage] = useState("");
  const [rating, setRating] = useState(5);
  const [ratingComment, setRatingComment] = useState("");
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [sending, setSending] = useState(false);

  useEffect(() => {
    void load();
    const timer = window.setInterval(() => void load({ silent: true }), 5000);
    return () => window.clearInterval(timer);
  }, []);

  const canRate = useMemo(
    () => Boolean(conversation && !conversation.rating && (conversation.ratingRequestedAt || conversation.status === "CLOSED")),
    [conversation]
  );

  async function load(options: { silent?: boolean } = {}) {
    if (!options.silent) setLoading(true);
    const response = await fetch("/api/support/livechat", { cache: "no-store" });
    const payload = await response.json();
    if (!options.silent) setLoading(false);
    if (!payload.ok) {
      if (!options.silent) setMessage(payload.error?.message ?? "Livechat indisponible");
      return;
    }
    setAvailability(payload.data.availability);
    setConversation(payload.data.conversation);
  }

  async function startChat() {
    setSending(true);
    setMessage("");
    const response = await fetch("/api/support/livechat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message: initialMessage })
    });
    const payload = await response.json();
    setSending(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Ouverture du livechat impossible");
      await load();
      return;
    }
    setInitialMessage("");
    setConversation(payload.data.conversation);
  }

  async function sendMessage() {
    if (!conversation || !draft.trim()) return;
    setSending(true);
    const response = await fetch(`/api/support/livechat/${conversation.id}/messages`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message: draft })
    });
    const payload = await response.json();
    setSending(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Message impossible");
      return;
    }
    setDraft("");
    setConversation(payload.data.conversation);
  }

  async function closeChat() {
    if (!conversation) return;
    const response = await fetch(`/api/support/livechat/${conversation.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "close" })
    });
    const payload = await response.json();
    if (payload.ok) setConversation(payload.data.conversation);
  }

  async function sendRating() {
    if (!conversation) return;
    setSending(true);
    const response = await fetch(`/api/support/livechat/${conversation.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action: "rate", rating, comment: ratingComment })
    });
    const payload = await response.json();
    setSending(false);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Notation impossible");
      return;
    }
    setConversation(payload.data.conversation);
  }

  return (
    <div className="mx-auto w-full max-w-[700px] space-y-2.5">
      <section className="rounded-lg border border-white/10 bg-[#101521] p-3 shadow-panel">
        <div className="flex items-start gap-2.5">
          <span className={cn("grid h-9 w-9 shrink-0 place-items-center rounded-lg", availability?.liveChatOnline ? "bg-felt/10 text-felt" : "bg-ember/10 text-ember")}>
            {availability?.liveChatOnline ? <Wifi className="h-4 w-4" /> : <WifiOff className="h-4 w-4" />}
          </span>
          <div className="min-w-0 flex-1">
            <p className="text-[11px] font-bold uppercase tracking-[0.14em] text-felt">Livechat</p>
            <h1 className="mt-1 text-lg font-bold text-white">{availability?.liveChatOnline ? "Support en ligne" : "Support hors ligne"}</h1>
            <p className="mt-1.5 text-xs leading-5 text-slate-400">
              {availability?.liveChatOnline
                ? "Un conseiller peut vous répondre directement ici."
                : "Le livechat est fermé pour le moment. Vous pouvez ouvrir un ticket support."}
            </p>
          </div>
        </div>
      </section>

      {message ? <div className="rounded-lg border border-ember/25 bg-ember/10 p-2.5 text-xs font-bold text-ember">{message}</div> : null}

      {!availability?.liveChatOnline && !conversation ? (
        <section className="rounded-lg border border-white/10 bg-[#101521] p-3 shadow-panel">
          <h2 className="text-sm font-bold text-white">Créer un ticket</h2>
          <p className="mt-1 text-xs leading-5 text-slate-400">
            {availability?.ticketResponseTime ?? "Réponse sous 2 à 3 heures"} pendant les horaires : {availability?.supportHours ?? "Lundi - Vendredi : 08:30 - 18:30"}.
          </p>
          <Link href="/support/tickets" className="mt-3 flex h-10 items-center justify-center rounded-lg bg-felt text-sm font-bold text-ink-950">
            Ouvrir un ticket
          </Link>
        </section>
      ) : null}

      {availability?.liveChatOnline && !conversation ? (
        <section className="rounded-lg border border-white/10 bg-[#101521] p-3 shadow-panel">
          <div className="flex items-center gap-2">
            <MessageCircle className="h-4 w-4 text-felt" />
            <h2 className="text-sm font-bold text-white">Nouvelle discussion</h2>
          </div>
          <textarea value={initialMessage} onChange={(event) => setInitialMessage(event.target.value)} className="mt-2 min-h-24 w-full rounded-lg border-white/10 bg-ink-900 text-sm text-white" placeholder="Expliquez brièvement votre demande..." />
          <button onClick={() => void startChat()} disabled={sending} className="mt-2 flex h-10 w-full items-center justify-center gap-2 rounded-lg bg-felt text-sm font-bold text-ink-950 disabled:opacity-50">
            {sending ? <Loader2 className="h-4 w-4 animate-spin" /> : <MessageCircle className="h-4 w-4" />}
            Démarrer le livechat
          </button>
        </section>
      ) : null}

      {conversation ? (
        <section className="rounded-lg border border-white/10 bg-[#101521] p-3 shadow-panel">
          <div className="flex items-center justify-between gap-3">
            <div>
              <h2 className="text-sm font-bold text-white">Discussion support</h2>
              <p className="mt-0.5 text-[11px] font-semibold text-slate-500">{conversation.status === "OPEN" ? "En cours" : "Fermée"}</p>
            </div>
            {conversation.status === "OPEN" ? (
              <button onClick={() => void closeChat()} className="h-8 rounded-lg border border-white/10 bg-white/[0.05] px-3 text-xs font-bold text-slate-200">
                Fermer
              </button>
            ) : null}
          </div>
          <div className="mt-3 max-h-[430px] space-y-2 overflow-y-auto rounded-lg border border-white/10 bg-black/15 p-2.5">
            {conversation.messages.map((chatMessage) => (
              <div key={chatMessage.id} className={cn("max-w-[88%] rounded-lg px-3 py-2", chatMessage.senderRole === "USER" ? "ml-auto bg-felt/15" : "bg-white/[0.06]")}>
                <div className="text-[10px] font-black uppercase text-slate-500">{chatMessage.senderRole === "USER" ? "Vous" : "Support"} · {formatDate(chatMessage.createdAt)}</div>
                <div className="mt-1 whitespace-pre-wrap text-sm font-semibold leading-5 text-white">{chatMessage.body}</div>
              </div>
            ))}
            {!conversation.messages.length ? <div className="text-xs font-semibold text-slate-500">Aucun message pour le moment.</div> : null}
          </div>

          {conversation.status === "OPEN" ? (
            <div className="mt-2 grid gap-2 sm:grid-cols-[1fr_auto]">
              <textarea value={draft} onChange={(event) => setDraft(event.target.value)} className="min-h-16 rounded-lg border-white/10 bg-ink-900 text-sm text-white" placeholder="Votre message..." />
              <button onClick={() => void sendMessage()} disabled={sending || !draft.trim()} className="flex h-10 items-center justify-center gap-2 rounded-lg bg-felt px-4 text-xs font-bold text-ink-950 disabled:opacity-50">
                <Send className="h-4 w-4" />
                Envoyer
              </button>
            </div>
          ) : null}

          {canRate ? (
            <div className="mt-3 rounded-lg border border-gold/20 bg-gold/10 p-3">
              <h3 className="text-sm font-bold text-white">Noter la discussion</h3>
              <div className="mt-2 flex gap-1">
                {[1, 2, 3, 4, 5].map((value) => (
                  <button key={value} onClick={() => setRating(value)} className="text-gold">
                    <Star className={cn("h-6 w-6", value <= rating && "fill-gold")} />
                  </button>
                ))}
              </div>
              <textarea value={ratingComment} onChange={(event) => setRatingComment(event.target.value)} className="mt-2 min-h-16 w-full rounded-lg border-white/10 bg-ink-900 text-sm text-white" placeholder="Votre avis..." />
              <button onClick={() => void sendRating()} disabled={sending} className="mt-2 h-9 w-full rounded-lg bg-gold text-xs font-bold text-ink-950 disabled:opacity-50">
                Envoyer mon avis
              </button>
            </div>
          ) : null}
        </section>
      ) : null}
    </div>
  );
}

function formatDate(value: string) {
  return new Intl.DateTimeFormat("fr-FR", { hour: "2-digit", minute: "2-digit" }).format(new Date(value));
}
