"use client";

import { useEffect, useRef, useState, useTransition, type FormEvent } from "react";
import { ArrowLeft, Send, Sparkles } from "lucide-react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import type { ChartInput } from "@/lib/tuvi/engine";

type Turn = { role: "user" | "assistant"; content: string };

type Props = {
  input: ChartInput;
  /** Display strings derived server-side so we don't recompute the chart here. */
  display: {
    fullName: string;
    gender: string;
    solarDate: string;
    lunarDate: string;
    timeRange: string;
    fiveElements: string;
    soulStar: string;
  };
};

const SUGGESTIONS = [
  "Năm nay sự nghiệp tôi ra sao?",
  "Tình duyên 2026 thế nào?",
  "Tài lộc cuối năm có khởi sắc không?",
  "Sức khỏe tôi cần lưu ý gì?",
];

export function VanMenhChat({ input, display }: Props) {
  const [turns, setTurns] = useState<Turn[]>([]);
  const [draft, setDraft] = useState("");
  const [streaming, setStreaming] = useState(false);
  const [providerName, setProviderName] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [, startTransition] = useTransition();
  const scrollRef = useRef<HTMLDivElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  // Auto-scroll on new content
  useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [turns]);

  async function send(text: string) {
    const question = text.trim();
    if (!question || streaming) return;
    setError(null);

    // Append user turn + empty assistant placeholder
    const history = turns.map((t) => ({
      role: t.role,
      content: t.content,
    }));
    setTurns((prev) => [
      ...prev,
      { role: "user", content: question },
      { role: "assistant", content: "" },
    ]);
    setDraft("");
    setStreaming(true);

    const ctrl = new AbortController();
    abortRef.current = ctrl;

    try {
      const res = await fetch("/api/ai/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ input, question, history }),
        signal: ctrl.signal,
      });

      if (!res.ok || !res.body) {
        const msg = (await res.text().catch(() => "")) || `HTTP ${res.status}`;
        throw new Error(msg);
      }

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

      while (true) {
        const { value, done } = await reader.read();
        if (done) break;
        buf += decoder.decode(value, { stream: true });

        const events = buf.split("\n\n");
        buf = events.pop() ?? "";
        for (const evt of events) {
          const trimmed = evt.trim();
          if (!trimmed.startsWith("data:")) continue;
          const payload = trimmed.slice(5).trim();
          try {
            const parsed = JSON.parse(payload) as {
              delta?: string;
              done?: boolean;
              provider?: string;
              error?: string;
            };
            if (parsed.error) throw new Error(parsed.error);
            if (parsed.provider) setProviderName(parsed.provider);
            if (parsed.delta) {
              startTransition(() => {
                setTurns((prev) => {
                  const next = prev.slice();
                  const last = next[next.length - 1];
                  if (last && last.role === "assistant") {
                    next[next.length - 1] = {
                      ...last,
                      content: last.content + parsed.delta,
                    };
                  }
                  return next;
                });
              });
            }
          } catch (e) {
            if (e instanceof Error && e.message !== "Unexpected end of JSON input") {
              throw e;
            }
          }
        }
      }
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Lỗi không xác định";
      // If user aborted, leave the partial assistant content in place.
      if (msg !== "AbortError" && !msg.includes("aborted")) {
        setError(msg);
      }
    } finally {
      setStreaming(false);
      abortRef.current = null;
    }
  }

  function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    void send(draft);
  }

  function stop() {
    abortRef.current?.abort();
  }

  return (
    <div className="bg-bg-base relative min-h-[80vh]">
      <div className="bagua-decor absolute inset-0 opacity-30" aria-hidden="true" />
      <div className="max-w-container relative mx-auto px-4 py-8 lg:px-6 lg:py-12">
        <div className="mb-6 flex items-center justify-between">
          <Link
            href="/van-menh"
            className="text-ink-secondary hover:text-brand-gold inline-flex items-center gap-1.5 text-sm"
          >
            <ArrowLeft className="h-4 w-4" aria-hidden="true" />
            Đổi lá số
          </Link>
          {providerName === "mock" ? (
            <span className="border-stroke-default text-ink-muted rounded-md border px-2 py-0.5 text-[11px] tracking-wider uppercase">
              mock mode
            </span>
          ) : null}
        </div>

        <div className="mx-auto max-w-3xl">
          {/* Chart summary card */}
          <div className="border-brand-gold/20 bg-bg-elevated/60 mb-6 rounded-xl border p-4 backdrop-blur-sm">
            <div className="ornament-line text-brand-gold-soft mb-2 text-xs tracking-[0.22em] uppercase">
              Vận mệnh &ldquo;Thầy&rdquo;
            </div>
            <h1 className="font-display text-xl font-semibold lg:text-2xl">
              Hỏi đáp với thầy tử vi
              {display.fullName ? ` — ${display.fullName}` : ""}
            </h1>
            <p className="text-ink-secondary mt-1.5 text-sm">
              {display.gender} · {display.solarDate} ({display.lunarDate}) · {display.timeRange}
              <span className="text-ink-muted"> · {display.fiveElements}</span>
            </p>
          </div>

          {/* Chat thread */}
          <div
            ref={scrollRef}
            className="border-stroke-default/60 bg-bg-elevated/30 mb-4 h-[55vh] overflow-y-auto rounded-xl border p-4 lg:p-6"
          >
            {turns.length === 0 ? (
              <div className="flex h-full flex-col items-center justify-center text-center">
                <Sparkles className="text-brand-gold/60 mb-3 h-8 w-8" aria-hidden="true" />
                <p className="text-ink-secondary mb-4 max-w-md text-sm">
                  Hãy hỏi về tình duyên, sự nghiệp, tài lộc, sức khỏe... &ldquo;Thầy&rdquo; sẽ luận
                  giải dựa trên lá số tử vi của bạn.
                </p>
                <div className="flex flex-wrap justify-center gap-2">
                  {SUGGESTIONS.map((s) => (
                    <button
                      key={s}
                      type="button"
                      onClick={() => void send(s)}
                      className="border-stroke-default text-ink-secondary hover:border-brand-gold/40 hover:text-brand-gold rounded-full border px-3 py-1.5 text-xs transition"
                    >
                      {s}
                    </button>
                  ))}
                </div>
              </div>
            ) : (
              <div className="space-y-4">
                {turns.map((t, i) => (
                  <div
                    key={i}
                    className={cn(
                      "max-w-[85%] rounded-xl px-4 py-3",
                      t.role === "user"
                        ? "border-brand-gold/30 bg-brand-gold/10 ml-auto border"
                        : "border-stroke-default bg-bg-inset border"
                    )}
                  >
                    <div className="text-ink-muted mb-1 text-[11px] tracking-wider uppercase">
                      {t.role === "user" ? "Bạn" : "Thầy"}
                    </div>
                    <div className="text-ink-primary text-sm leading-relaxed whitespace-pre-wrap">
                      {t.content || (streaming && i === turns.length - 1 ? "..." : "")}
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>

          {error ? (
            <div className="border-brand-red/40 bg-brand-red/10 text-brand-red-light mb-3 rounded-md border px-4 py-2 text-sm">
              {error}
            </div>
          ) : null}

          {/* Composer */}
          <form
            onSubmit={handleSubmit}
            className="border-stroke-default bg-bg-inset flex items-end gap-2 rounded-xl border p-3"
          >
            <textarea
              value={draft}
              onChange={(e) => setDraft(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter" && !e.shiftKey && !streaming) {
                  e.preventDefault();
                  void send(draft);
                }
              }}
              rows={2}
              maxLength={500}
              placeholder="Hỏi thầy về vận mệnh của bạn..."
              className="text-ink-primary placeholder:text-ink-muted/60 flex-1 resize-none bg-transparent px-2 py-1.5 text-sm focus:outline-none"
              disabled={streaming}
            />
            {streaming ? (
              <button
                type="button"
                onClick={stop}
                className="border-stroke-default text-ink-secondary hover:border-brand-red/50 hover:text-brand-red-light rounded-md border px-4 py-2.5 text-sm"
              >
                Dừng
              </button>
            ) : (
              <button
                type="submit"
                disabled={!draft.trim()}
                className="from-brand-gold via-brand-gold-soft to-brand-gold text-bg-base flex items-center gap-1.5 rounded-md bg-gradient-to-r px-4 py-2.5 text-sm font-semibold transition hover:brightness-105 disabled:opacity-50"
              >
                <Send className="h-3.5 w-3.5" aria-hidden="true" />
                Gửi
              </button>
            )}
          </form>
          <p className="text-ink-muted mt-2 text-center text-[11px]">
            Nội dung chỉ mang tính tham khảo. Không thay thế lời khuyên y tế / tài chính / pháp lý.
          </p>
        </div>
      </div>
    </div>
  );
}
