"use client";

import { useEffect, useMemo, useState } from "react";
import type { ReactNode } from "react";
import { MessageCircle, RefreshCw, Send, Star, Ticket, Wifi, WifiOff } from "lucide-react";
import { cn } from "@/lib/utils";

type SupportMessage = {
  id: string;
  senderRole: "USER" | "ADMIN" | "SYSTEM";
  body: string;
  createdAt: string;
  sender: { email: string; username: string } | null;
};

type SupportTicket = {
  id: string;
  subject: string;
  category: string;
  status: string;
  priority: string;
  lastMessageAt: string;
  user: { email: string; username: string };
  messages: SupportMessage[];
};

type LiveChatConversation = {
  id: string;
  status: string;
  lastMessageAt: string;
  rating: number | null;
  ratingComment: string | null;
  ratingRequestedAt: string | null;
  user: { email: string; username: string };
  assignedAdmin: { email: string; username: string } | null;
  messages: SupportMessage[];
};

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

export function AdminSupportDashboard() {
  const [availability, setAvailability] = useState<Availability | null>(null);
  const [tickets, setTickets] = useState<SupportTicket[]>([]);
  const [conversations, setConversations] = useState<LiveChatConversation[]>([]);
  const [tab, setTab] = useState<"tickets" | "livechat">("livechat");
  const [selectedTicketId, setSelectedTicketId] = useState<string | null>(null);
  const [selectedConversationId, setSelectedConversationId] = useState<string | null>(null);
  const [reply, setReply] = useState("");
  const [message, setMessage] = useState("");
  const [loading, setLoading] = useState(true);
  const [actionId, setActionId] = useState<string | null>(null);

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

  useEffect(() => {
    if (!selectedTicketId && tickets.length) setSelectedTicketId(tickets[0].id);
  }, [selectedTicketId, tickets]);

  useEffect(() => {
    if (!selectedConversationId && conversations.length) setSelectedConversationId(conversations[0].id);
  }, [conversations, selectedConversationId]);

  const selectedTicket = useMemo(() => tickets.find((ticketItem) => ticketItem.id === selectedTicketId) ?? tickets[0] ?? null, [tickets, selectedTicketId]);
  const selectedConversation = useMemo(
    () => conversations.find((conversation) => conversation.id === selectedConversationId) ?? conversations[0] ?? null,
    [conversations, selectedConversationId]
  );
  const activeItems = tab === "tickets" ? tickets : conversations;

  async function load(options: { silent?: boolean } = {}) {
    if (!options.silent) {
      setLoading(true);
      setMessage("");
    }
    const response = await fetch("/api/admin/support/overview", { cache: "no-store" });
    const payload = await response.json();
    if (!options.silent) setLoading(false);
    if (!payload.ok) {
      if (!options.silent) setMessage(payload.error?.message ?? "Chargement support impossible");
      return;
    }
    setAvailability(payload.data.availability);
    setTickets(payload.data.tickets);
    setConversations(payload.data.conversations);
  }

  async function toggleAvailability() {
    if (!availability) return;
    setActionId("availability");
    const response = await fetch("/api/admin/support/availability", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        liveChatOnline: !availability.liveChatOnline,
        message: !availability.liveChatOnline ? "Support en ligne" : "Support hors ligne"
      })
    });
    const payload = await response.json();
    setActionId(null);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Modification disponibilité impossible");
      return;
    }
    setAvailability(payload.data);
  }

  async function sendTicketReply() {
    if (!selectedTicket || !reply.trim()) return;
    setActionId("ticket-reply");
    const response = await fetch(`/api/admin/support/tickets/${selectedTicket.id}/messages`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message: reply })
    });
    await handleDeskResponse(response, () => setReply(""));
  }

  async function updateTicket(input: { status?: string; priority?: string; assignToMe?: boolean }) {
    if (!selectedTicket) return;
    setActionId("ticket-update");
    const response = await fetch(`/api/admin/support/tickets/${selectedTicket.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(input)
    });
    await handleDeskResponse(response);
  }

  async function sendChatReply() {
    if (!selectedConversation || !reply.trim()) return;
    setActionId("chat-reply");
    const response = await fetch(`/api/admin/support/livechat/${selectedConversation.id}/messages`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ message: reply })
    });
    await handleDeskResponse(response, () => setReply(""));
  }

  async function patchChat(action: "close" | "request_rating") {
    if (!selectedConversation) return;
    setActionId(`chat-${action}`);
    const response = await fetch(`/api/admin/support/livechat/${selectedConversation.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action })
    });
    await handleDeskResponse(response);
  }

  async function deleteChat() {
    if (!selectedConversation) return;
    setActionId("chat-delete");
    const response = await fetch(`/api/admin/support/livechat/${selectedConversation.id}`, { method: "DELETE" });
    await handleDeskResponse(response, () => setSelectedConversationId(null));
  }

  async function handleDeskResponse(response: Response, onSuccess?: () => void) {
    const payload = await response.json();
    setActionId(null);
    if (!payload.ok) {
      setMessage(payload.error?.message ?? "Action support impossible");
      return;
    }
    onSuccess?.();
    await load({ silent: true });
  }

  return (
    <section className="surface rounded-lg p-4">
      <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
        <div className="flex items-center gap-2">
          <MessageCircle className="h-5 w-5 text-felt" />
          <div>
            <h2 className="text-lg font-black text-white">Support desk</h2>
            <p className="mt-0.5 text-xs font-semibold text-slate-500">Tickets, livechat, fermeture, historique et notation client.</p>
          </div>
        </div>
        <div className="flex flex-wrap gap-2">
          <button
            onClick={() => void toggleAvailability()}
            className={cn(
              "flex h-9 items-center gap-2 rounded-lg px-3 text-xs font-black",
              availability?.liveChatOnline ? "bg-felt text-ink-950" : "border border-white/10 bg-white/[0.06] text-slate-200"
            )}
          >
            {availability?.liveChatOnline ? <Wifi className="h-4 w-4" /> : <WifiOff className="h-4 w-4" />}
            {availability?.liveChatOnline ? "Livechat en ligne" : "Livechat hors ligne"}
          </button>
          <button onClick={() => void load()} className="grid h-9 w-9 place-items-center rounded-lg bg-white/[0.06] text-slate-200">
            <RefreshCw className={cn("h-4 w-4", loading && "animate-spin")} />
          </button>
        </div>
      </div>

      {availability ? (
        <div className="mt-3 rounded-lg border border-white/10 bg-white/[0.035] p-3 text-xs font-semibold text-slate-400">
          Tickets : {availability.ticketResponseTime}. Horaires : {availability.supportHours}.
        </div>
      ) : null}
      {message ? <div className="mt-3 rounded-lg border border-ember/25 bg-ember/10 p-2.5 text-xs font-bold text-ember">{message}</div> : null}

      <div className="mt-4 grid gap-3 xl:grid-cols-[0.78fr_1.22fr]">
        <div className="overflow-hidden rounded-lg border border-white/10">
          <div className="grid grid-cols-2 border-b border-white/10 bg-white/[0.035] p-1">
            <TabButton active={tab === "livechat"} onClick={() => setTab("livechat")} icon={<MessageCircle className="h-4 w-4" />} label={`Livechat (${conversations.length})`} />
            <TabButton active={tab === "tickets"} onClick={() => setTab("tickets")} icon={<Ticket className="h-4 w-4" />} label={`Tickets (${tickets.length})`} />
          </div>
          <div className="max-h-[620px] divide-y divide-white/10 overflow-y-auto">
            {activeItems.map((item) =>
              tab === "tickets" ? (
                <TicketListItem key={item.id} ticket={item as SupportTicket} active={selectedTicket?.id === item.id} onClick={() => setSelectedTicketId(item.id)} />
              ) : (
                <ChatListItem key={item.id} conversation={item as LiveChatConversation} active={selectedConversation?.id === item.id} onClick={() => setSelectedConversationId(item.id)} />
              )
            )}
            {!activeItems.length ? <div className="p-4 text-sm font-semibold text-slate-500">Aucun élément.</div> : null}
          </div>
        </div>

        <div className="rounded-lg border border-white/10 bg-white/[0.025] p-3">
          {tab === "tickets" && selectedTicket ? (
            <DeskPane
              title={selectedTicket.subject}
              subtitle={`${selectedTicket.user.email} · ${selectedTicket.category}`}
              status={selectedTicket.status}
              messages={selectedTicket.messages}
              reply={reply}
              setReply={setReply}
              onSend={() => void sendTicketReply()}
              sendDisabled={actionId === "ticket-reply"}
              actions={
                <>
                  <select
                    value={selectedTicket.priority}
                    onChange={(event) => void updateTicket({ priority: event.target.value })}
                    className="h-9 rounded-lg border border-white/10 bg-[#101521] px-2 text-xs font-bold text-white"
                  >
                    {["LOW", "NORMAL", "HIGH", "URGENT"].map((item) => (
                      <option key={item} value={item}>
                        {item}
                      </option>
                    ))}
                  </select>
                  <button onClick={() => void updateTicket({ assignToMe: true })} className="h-9 rounded-lg bg-felt px-3 text-xs font-black text-ink-950">
                    M'assigner
                  </button>
                  <button onClick={() => void updateTicket({ status: "RESOLVED" })} className="h-9 rounded-lg border border-felt/30 bg-felt/10 px-3 text-xs font-black text-felt">
                    Résolu
                  </button>
                </>
              }
            />
          ) : null}

          {tab === "livechat" && selectedConversation ? (
            <DeskPane
              title={`Discussion ${selectedConversation.user.username}`}
              subtitle={`${selectedConversation.user.email} · ${selectedConversation.assignedAdmin?.email ?? "non assignée"}`}
              status={selectedConversation.status}
              messages={selectedConversation.messages}
              reply={reply}
              setReply={setReply}
              onSend={() => void sendChatReply()}
              sendDisabled={actionId === "chat-reply" || selectedConversation.status !== "OPEN"}
              rating={selectedConversation.rating}
              ratingComment={selectedConversation.ratingComment}
              actions={
                <>
                  <button onClick={() => void patchChat("request_rating")} className="h-9 rounded-lg border border-gold/30 bg-gold/10 px-3 text-xs font-black text-gold">
                    Demander une note
                  </button>
                  <button onClick={() => void patchChat("close")} className="h-9 rounded-lg border border-felt/30 bg-felt/10 px-3 text-xs font-black text-felt">
                    Fermer
                  </button>
                  <button onClick={() => void deleteChat()} className="h-9 rounded-lg border border-ember/30 bg-ember/10 px-3 text-xs font-black text-ember">
                    Supprimer
                  </button>
                </>
              }
            />
          ) : null}
        </div>
      </div>
    </section>
  );
}

function DeskPane({
  title,
  subtitle,
  status,
  messages,
  reply,
  setReply,
  onSend,
  sendDisabled,
  actions,
  rating,
  ratingComment
}: {
  title: string;
  subtitle: string;
  status: string;
  messages: SupportMessage[];
  reply: string;
  setReply: (value: string) => void;
  onSend: () => void;
  sendDisabled: boolean;
  actions: ReactNode;
  rating?: number | null;
  ratingComment?: string | null;
}) {
  return (
    <div>
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div className="min-w-0">
          <h3 className="truncate text-lg font-black text-white">{title}</h3>
          <p className="mt-1 text-xs font-semibold text-slate-500">{subtitle}</p>
        </div>
        <StatusBadge status={status} />
      </div>
      {rating ? (
        <div className="mt-3 rounded-lg border border-gold/20 bg-gold/10 p-2.5 text-xs font-semibold text-gold">
          Note client : {"★".repeat(rating)}{"☆".repeat(5 - rating)}
          {ratingComment ? <span className="block pt-1 text-slate-300">{ratingComment}</span> : null}
        </div>
      ) : null}
      <div className="mt-3 flex flex-wrap gap-2">{actions}</div>
      <div className="mt-4 max-h-[420px] space-y-2 overflow-y-auto rounded-lg border border-white/10 bg-[#101521] p-3">
        {messages.map((chatMessage) => (
          <div key={chatMessage.id} className={cn("max-w-[86%] rounded-lg px-3 py-2", chatMessage.senderRole === "ADMIN" ? "ml-auto bg-felt/15" : "bg-white/[0.06]")}>
            <div className="text-[10px] font-black uppercase text-slate-500">{chatMessage.senderRole === "ADMIN" ? "Support" : chatMessage.sender?.username ?? "Client"} · {formatTime(chatMessage.createdAt)}</div>
            <div className="mt-1 whitespace-pre-wrap text-sm font-semibold leading-5 text-white">{chatMessage.body}</div>
          </div>
        ))}
        {!messages.length ? <div className="text-sm font-semibold text-slate-500">Aucun message.</div> : null}
      </div>
      <div className="mt-3 grid gap-2 sm:grid-cols-[1fr_auto]">
        <textarea value={reply} onChange={(event) => setReply(event.target.value)} className="min-h-20 rounded-lg border-white/10 bg-ink-900 text-sm text-white" placeholder="Réponse support..." />
        <button onClick={onSend} disabled={sendDisabled || !reply.trim()} className="flex h-10 items-center justify-center gap-2 rounded-lg bg-felt px-4 text-xs font-black text-ink-950 disabled:opacity-50">
          <Send className="h-4 w-4" />
          Envoyer
        </button>
      </div>
    </div>
  );
}

function TabButton({ active, onClick, icon, label }: { active: boolean; onClick: () => void; icon: ReactNode; label: string }) {
  return (
    <button onClick={onClick} className={cn("flex h-9 items-center justify-center gap-2 rounded-lg text-xs font-black", active ? "bg-felt text-ink-950" : "text-slate-400")}>
      {icon}
      {label}
    </button>
  );
}

function TicketListItem({ ticket, active, onClick }: { ticket: SupportTicket; active: boolean; onClick: () => void }) {
  return (
    <button onClick={onClick} className={cn("block w-full px-3 py-3 text-left transition", active ? "bg-felt/10" : "bg-white/[0.02] hover:bg-white/[0.05]")}>
      <div className="flex items-center justify-between gap-2">
        <span className="truncate text-sm font-black text-white">{ticket.subject}</span>
        <StatusBadge status={ticket.status} />
      </div>
      <div className="mt-1 text-[11px] font-semibold text-slate-500">{ticket.user.email} · {ticket.priority} · {formatTime(ticket.lastMessageAt)}</div>
    </button>
  );
}

function ChatListItem({ conversation, active, onClick }: { conversation: LiveChatConversation; active: boolean; onClick: () => void }) {
  return (
    <button onClick={onClick} className={cn("block w-full px-3 py-3 text-left transition", active ? "bg-felt/10" : "bg-white/[0.02] hover:bg-white/[0.05]")}>
      <div className="flex items-center justify-between gap-2">
        <span className="truncate text-sm font-black text-white">{conversation.user.email}</span>
        <StatusBadge status={conversation.status} />
      </div>
      <div className="mt-1 flex items-center gap-1.5 text-[11px] font-semibold text-slate-500">
        {conversation.rating ? <Star className="h-3 w-3 fill-gold text-gold" /> : null}
        <span>{conversation.messages.length} messages · {formatTime(conversation.lastMessageAt)}</span>
      </div>
    </button>
  );
}

function StatusBadge({ status }: { status: string }) {
  const tone = status.includes("OPEN") || status.includes("WAITING") ? "bg-gold/10 text-gold" : status.includes("RESOLVED") || status.includes("CLOSED") ? "bg-felt/10 text-felt" : "bg-white/[0.08] text-slate-300";
  return <span className={cn("w-fit rounded-md px-2 py-1 text-[10px] font-black uppercase", tone)}>{status}</span>;
}

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