"use client";

import { useEffect, useRef, useState } from "react";
import {
  ArrowUp,
  FileText,
  ListChecks,
  Quote,
  ScanSearch,
  Sparkles,
  SquareStack,
  StopCircle,
} from "lucide-react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

import { streamChat } from "@/lib/api";
import type { Citation, DocumentDetail } from "@/lib/types";

interface Msg {
  role: "user" | "assistant";
  content: string;
  citations?: Citation[];
}

const SUGGESTIONS = [
  { icon: SquareStack, text: "Summarize this document" },
  { icon: ScanSearch, text: "What type of document is this?" },
  { icon: ListChecks, text: "Extract all the key fields" },
  { icon: Sparkles, text: "Are there any missing fields or anomalies?" },
];

export default function ChatPanel({
  documentId,
  detail,
  provider,
  onCitationClick,
}: {
  documentId: string | null;
  detail: DocumentDetail | null;
  provider: string | null;
  onCitationClick: (c: Citation) => void;
}) {
  const [messages, setMessages] = useState<Msg[]>([]);
  const [input, setInput] = useState("");
  const [busy, setBusy] = useState(false);
  const abortRef = useRef<AbortController | null>(null);
  const scrollRef = useRef<HTMLDivElement>(null);
  const taRef = useRef<HTMLTextAreaElement>(null);

  useEffect(() => setMessages([]), [documentId]);

  useEffect(() => {
    scrollRef.current?.scrollTo({
      top: scrollRef.current.scrollHeight,
      behavior: "smooth",
    });
  }, [messages, busy]);

  // autosize composer
  useEffect(() => {
    const ta = taRef.current;
    if (!ta) return;
    ta.style.height = "auto";
    ta.style.height = Math.min(ta.scrollHeight, 140) + "px";
  }, [input]);

  const send = async (text: string) => {
    const q = text.trim();
    if (!q || busy) return;
    const history = [...messages, { role: "user" as const, content: q }];
    setMessages([...history, { role: "assistant", content: "" }]);
    setInput("");
    setBusy(true);

    abortRef.current = new AbortController();
    await streamChat(
      {
        document_id: documentId,
        provider,
        messages: history.map((m) => ({ role: m.role, content: m.content })),
      },
      {
        onToken: (t) =>
          setMessages((prev) => {
            const next = [...prev];
            const last = next[next.length - 1];
            next[next.length - 1] = { ...last, content: last.content + t };
            return next;
          }),
        onCitations: (c) =>
          setMessages((prev) => {
            const next = [...prev];
            next[next.length - 1] = { ...next[next.length - 1], citations: c };
            return next;
          }),
        onDone: () => setBusy(false),
        onError: (msg) =>
          setMessages((prev) => {
            const next = [...prev];
            const last = next[next.length - 1];
            next[next.length - 1] = {
              role: "assistant",
              content: (last.content || "") + `\n\n_⚠️ ${msg}_`,
            };
            return next;
          }),
      },
      abortRef.current.signal,
    );
    setBusy(false);
  };

  const stop = () => {
    abortRef.current?.abort();
    setBusy(false);
  };

  const ready = detail?.status === "ready";
  const lastIsStreaming = busy;

  return (
    <div className="flex h-full flex-col">
      {/* messages */}
      <div ref={scrollRef} className="min-h-0 flex-1 space-y-5 overflow-y-auto px-4 py-5">
        {messages.length === 0 && (
          <div className="flex h-full flex-col items-center justify-center px-2 text-center">
            <div className="relative mb-4">
              <div className="absolute inset-0 animate-pulse-soft rounded-2xl bg-brand-500/20 blur-xl" />
              <div className="relative flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-brand-400/30 to-brand-700/10 ring-1 ring-brand-500/30">
                <Sparkles className="text-brand-200" size={24} />
              </div>
            </div>
            <h2 className="text-[15px] font-semibold text-white">
              {documentId ? "Ask about this document" : "Upload a document to begin"}
            </h2>
            <p className="mt-1.5 max-w-[280px] text-xs leading-relaxed text-white/45">
              {documentId
                ? "I can summarize, classify, extract structured data, and answer questions — each grounded with clickable citations."
                : "Drop a PDF, Word file, or image in the left rail. I'll parse it, then you can chat about it."}
            </p>
            {documentId && (
              <div className="mt-6 grid w-full max-w-[320px] gap-2">
                {SUGGESTIONS.map((s) => {
                  const Icon = s.icon;
                  return (
                    <button
                      key={s.text}
                      onClick={() => send(s.text)}
                      disabled={!ready}
                      className="group flex items-center gap-2.5 rounded-xl border border-white/[0.06] bg-surface-850/60 px-3 py-2.5 text-left text-xs text-white/70 transition hover:border-brand-500/40 hover:bg-surface-800 hover:text-white disabled:opacity-40"
                    >
                      <Icon
                        size={14}
                        className="text-white/35 transition group-hover:text-brand-300"
                      />
                      {s.text}
                    </button>
                  );
                })}
              </div>
            )}
            {documentId && !ready && (
              <p className="mt-5 flex items-center gap-1.5 text-[11px] text-brand-300">
                <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-brand-400" />
                Processing… you can chat once it's ready.
              </p>
            )}
          </div>
        )}

        {messages.map((m, i) => {
          const streaming = lastIsStreaming && i === messages.length - 1;
          return (
            <div key={i} className="animate-fade-up">
              {m.role === "user" ? (
                <div className="flex justify-end">
                  <div className="max-w-[85%] rounded-2xl rounded-br-md bg-gradient-to-br from-brand-500 to-brand-600 px-3.5 py-2.5 text-sm text-white shadow-soft">
                    {m.content}
                  </div>
                </div>
              ) : (
                <div className="flex gap-2.5">
                  <div className="mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-brand-400 to-brand-700 ring-1 ring-white/10">
                    <Sparkles size={13} className="text-white" />
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="rounded-2xl rounded-tl-md border border-white/[0.06] bg-surface-850/80 px-3.5 py-2.5">
                      {!m.content && streaming ? (
                        <span className="flex gap-1 py-1.5">
                          <span className="typing-dot h-1.5 w-1.5 rounded-full bg-white/50" />
                          <span className="typing-dot h-1.5 w-1.5 rounded-full bg-white/50" />
                          <span className="typing-dot h-1.5 w-1.5 rounded-full bg-white/50" />
                        </span>
                      ) : (
                        <div className={`prose-chat ${streaming ? "caret" : ""}`}>
                          <ReactMarkdown remarkPlugins={[remarkGfm]}>
                            {m.content}
                          </ReactMarkdown>
                        </div>
                      )}
                    </div>

                    {m.citations && m.citations.length > 0 && (
                      <div className="mt-2 flex flex-wrap gap-1.5">
                        <span className="flex items-center gap-1 text-[10px] font-medium text-white/30">
                          <Quote size={9} /> Sources:
                        </span>
                        {m.citations.map((c, ci) => (
                          <button
                            key={ci}
                            onClick={() => onCitationClick(c)}
                            title={c.text}
                            className="flex items-center gap-1 rounded-md bg-brand-500/10 px-1.5 py-0.5 text-[10px] font-medium text-brand-200 ring-1 ring-brand-500/25 transition hover:bg-brand-500/20"
                          >
                            <FileText size={9} />p{c.page + 1}
                            <span className="text-brand-300/60">[{ci + 1}]</span>
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>

      {/* composer */}
      <div className="px-3 pb-3 pt-1">
        <div className="flex items-end gap-2 rounded-2xl border border-white/[0.08] bg-surface-850/80 p-2 shadow-soft transition focus-within:border-brand-500/50 focus-within:shadow-glow">
          <textarea
            ref={taRef}
            rows={1}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter" && !e.shiftKey) {
                e.preventDefault();
                send(input);
              }
            }}
            placeholder={
              documentId ? "Ask anything about this document…" : "Upload a document first…"
            }
            disabled={!documentId}
            className="max-h-36 min-h-[26px] flex-1 resize-none bg-transparent px-1.5 py-1 text-sm text-white placeholder:text-white/30 focus:outline-none disabled:opacity-50"
          />
          {busy ? (
            <button
              onClick={stop}
              className="flex h-8 w-8 shrink-0 items-center justify-center rounded-xl bg-rose-500/20 text-rose-300 transition hover:bg-rose-500/30"
              title="Stop"
            >
              <StopCircle size={16} />
            </button>
          ) : (
            <button
              onClick={() => send(input)}
              disabled={!input.trim() || !documentId}
              className="flex h-8 w-8 shrink-0 items-center justify-center rounded-xl bg-gradient-to-br from-brand-500 to-brand-600 text-white transition hover:from-brand-400 hover:to-brand-500 disabled:cursor-not-allowed disabled:opacity-30"
              title="Send"
            >
              <ArrowUp size={16} />
            </button>
          )}
        </div>
        <p className="mt-1.5 px-2 text-center text-[10px] text-white/25">
          Grounded in your document · click a source to highlight it ·{" "}
          <kbd className="rounded bg-white/[0.06] px-1 text-white/40">Enter</kbd> to send
        </p>
      </div>
    </div>
  );
}
