"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { usePathname } from "next/navigation";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { Zap, Send, Loader2, ChevronDown, Clock, DollarSign } from "lucide-react";

interface WidgetMessage {
  id: string;
  role: "user" | "assistant";
  content: string;
  model?: string;
  costUsd?: number;
  latencyMs?: number;
}

export default function TokenWidget() {
  const pathname = usePathname();
  const [open, setOpen] = useState(false);
  const [messages, setMessages] = useState<WidgetMessage[]>([]);
  const [conversationId, setConversationId] = useState<string | null>(null);
  const [input, setInput] = useState("");
  const [sending, setSending] = useState(false);
  const [streaming, setStreaming] = useState(false);
  const [alertCount, setAlertCount] = useState(0);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Hide on the full Token page
  const hidden = pathname === "/dashboard/token";

  // Fetch unread alert count on mount
  useEffect(() => {
    if (hidden) return;
    fetch("/api/token/alerts")
      .then((r) => r.json())
      .then((data) => {
        const alerts = data.alerts ?? [];
        const unread = alerts.filter(
          (a: { acknowledged: boolean; severity: string }) =>
            !a.acknowledged && (a.severity === "critical" || a.severity === "warning"),
        );
        setAlertCount(unread.length);
      })
      .catch(() => {});
  }, [hidden]);

  // Scroll to bottom on new messages
  const scrollToBottom = useCallback(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, []);

  useEffect(() => {
    scrollToBottom();
  }, [messages, scrollToBottom]);

  // Focus input when panel opens
  useEffect(() => {
    if (open) {
      setTimeout(() => inputRef.current?.focus(), 100);
    }
  }, [open]);

  async function sendMessage(e: React.FormEvent) {
    e.preventDefault();
    const msg = input.trim();
    if (!msg || sending) return;

    setInput("");
    setSending(true);

    const userMsg: WidgetMessage = {
      id: `tmp-${Date.now()}`,
      role: "user",
      content: msg,
    };
    setMessages((prev) => [...prev, userMsg]);

    const assistantId = `resp-${Date.now()}`;

    try {
      const res = await fetch("/api/token/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          message: msg,
          conversationId,
          stream: true,
        }),
      });

      if (!res.ok) {
        const data = await res.json();
        setMessages((prev) => [
          ...prev,
          { id: assistantId, role: "assistant", content: data.error || "Token failed to respond" },
        ]);
        return;
      }

      setMessages((prev) => [...prev, { id: assistantId, role: "assistant", content: "" }]);

      const reader = res.body!.getReader();
      const decoder = new TextDecoder();
      let buffer = "";

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split("\n");
        buffer = lines.pop() ?? "";

        for (const line of lines) {
          const trimmed = line.trim();
          if (!trimmed.startsWith("data: ")) continue;

          const jsonStr = trimmed.slice(6);
          if (jsonStr === "[DONE]") continue;

          try {
            const event = JSON.parse(jsonStr);

            if (event.conversationId && !event.done) {
              if (!conversationId) {
                setConversationId(event.conversationId);
              }
              continue;
            }

            if (event.done) {
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantId
                    ? { ...m, model: event.model, costUsd: event.costUsd, latencyMs: event.latencyMs }
                    : m,
                ),
              );
              continue;
            }

            if (event.token) {
              setStreaming(true);
              setMessages((prev) =>
                prev.map((m) =>
                  m.id === assistantId ? { ...m, content: m.content + event.token } : m,
                ),
              );
            }
          } catch {
            // Skip malformed SSE lines
          }
        }
      }
    } catch {
      setMessages((prev) => [
        ...prev.filter((m) => m.id !== assistantId),
        { id: assistantId, role: "assistant", content: "Failed to reach Token. Check your connection." },
      ]);
    } finally {
      setSending(false);
      setStreaming(false);
    }
  }

  if (hidden) return null;

  // Collapsed: floating button
  if (!open) {
    return (
      <button
        onClick={() => setOpen(true)}
        className="fixed bottom-6 right-6 z-50 flex h-14 w-14 items-center justify-center rounded-full bg-indigo-500 text-white shadow-lg transition-transform hover:scale-110 hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-950"
        aria-label="Open Token assistant"
        data-testid="token-widget-button"
      >
        <Zap className="h-6 w-6" />
        {alertCount > 0 && (
          <span
            className="absolute -right-1 -top-1 flex h-5 min-w-5 items-center justify-center rounded-full bg-red-500 px-1 text-xs font-bold text-white"
            data-testid="token-widget-badge"
          >
            {alertCount}
          </span>
        )}
      </button>
    );
  }

  // Expanded: chat panel
  return (
    <div
      className="fixed bottom-6 right-6 z-50 flex w-96 flex-col rounded-lg border border-gray-800 bg-gray-900 shadow-2xl"
      style={{ height: "500px" }}
      data-testid="token-widget-panel"
    >
      {/* Header */}
      <div className="flex items-center gap-2 border-b border-gray-800 px-4 py-3">
        <div className="flex h-8 w-8 items-center justify-center rounded-full bg-indigo-500/20">
          <Zap className="h-4 w-4 text-indigo-400" />
        </div>
        <span className="text-sm font-semibold text-gray-100">Token</span>
        <button
          onClick={() => setOpen(false)}
          className="ml-auto rounded p-1 text-gray-400 transition-colors hover:bg-gray-800 hover:text-gray-100"
          aria-label="Minimize Token"
          data-testid="token-widget-minimize"
        >
          <ChevronDown size={18} />
        </button>
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto px-3 py-3">
        {messages.length === 0 ? (
          <div className="flex h-full flex-col items-center justify-center gap-2 text-center">
            <Zap className="h-8 w-8 text-indigo-400/50" />
            <p className="text-xs text-gray-500">
              Ask Token about models, hardware, or fleet management.
            </p>
          </div>
        ) : (
          <div className="space-y-3">
            {messages.map((msg) => (
              <div
                key={msg.id}
                className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"}`}
              >
                <div
                  className={`max-w-[85%] rounded-lg px-3 py-2 text-sm ${
                    msg.role === "user"
                      ? "bg-indigo-500/20 text-gray-100"
                      : "bg-gray-800 text-gray-200"
                  }`}
                >
                  {msg.role === "assistant" ? (
                    <div className="prose prose-sm prose-invert max-w-none prose-pre:bg-transparent prose-pre:p-0">
                      <ReactMarkdown remarkPlugins={[remarkGfm]}>
                        {msg.content || "..."}
                      </ReactMarkdown>
                    </div>
                  ) : (
                    <div className="whitespace-pre-wrap">{msg.content}</div>
                  )}
                  {msg.role === "assistant" && (msg.model || msg.latencyMs || msg.costUsd) && (
                    <div className="mt-1 flex items-center gap-2 border-t border-gray-700/50 pt-1 text-[10px] text-gray-500">
                      {msg.model && <span>{msg.model}</span>}
                      {msg.latencyMs != null && (
                        <span className="flex items-center gap-0.5">
                          <Clock size={9} /> {(msg.latencyMs / 1000).toFixed(1)}s
                        </span>
                      )}
                      {msg.costUsd != null && msg.costUsd > 0 && (
                        <span className="flex items-center gap-0.5">
                          <DollarSign size={9} /> ${msg.costUsd.toFixed(4)}
                        </span>
                      )}
                    </div>
                  )}
                </div>
              </div>
            ))}
            {sending && !streaming && (
              <div className="flex justify-start">
                <div className="flex items-center gap-2 rounded-lg bg-gray-800 px-3 py-2 text-xs text-gray-400">
                  <Loader2 className="h-3 w-3 animate-spin" />
                  Token is thinking...
                </div>
              </div>
            )}
            <div ref={messagesEndRef} />
          </div>
        )}
      </div>

      {/* Input */}
      <form onSubmit={sendMessage} className="border-t border-gray-800 p-3">
        <div className="flex items-center gap-2">
          <input
            ref={inputRef}
            type="text"
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Ask Token..."
            maxLength={10000}
            className="flex-1 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-100 placeholder-gray-500 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
            data-testid="token-widget-input"
          />
          <button
            type="submit"
            disabled={sending || !input.trim()}
            className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-indigo-500 text-white transition-colors hover:bg-indigo-600 disabled:opacity-50 disabled:pointer-events-none"
            aria-label="Send message"
            data-testid="token-widget-send"
          >
            {sending ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send size={14} />}
          </button>
        </div>
      </form>
    </div>
  );
}
