import { useEffect, useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { aiApi, type AIDebugLog, type AITraderDebugEvent } from "../lib/ai";
import { AppIcon } from "./PixelIcons";

const SOURCE_LABELS: Record<string, string> = {
  ai_trader_pre_market: "交易員 · 市場分析",
  ai_trader_intraday: "交易員 · 盤中執行",
  ai_trader_intraday_review: "交易員 · 盤中復盤",
  ai_trader_post_market: "交易員 · 盤後復盤",
  ai_trader_chat: "交易員 · 對話",
  owl_guide: "貓頭鷹 · 導覽對話",
  owl_coach: "貓頭鷹 · 心法教練",
  owl_skill_assess: "貓頭鷹 · 心法評分",
  unknown: "其他 AI 呼叫",
};

function sourceLabel(source: string) {
  return SOURCE_LABELS[source] || source.replace(/_/g, " ");
}

function formatJSON(value: unknown) {
  return JSON.stringify(value, null, 2);
}

function formatTokens(value: number) {
  return value >= 1_000_000 ? `${(value / 1_000_000).toFixed(2)}M` : value >= 1_000 ? `${(value / 1_000).toFixed(1)}K` : value.toLocaleString();
}

function formatCost(value?: number | null) {
  if (value == null) return "價格未知";
  if (value < 0.01) return `$${value.toFixed(5)}`;
  return `$${value.toFixed(3)}`;
}

function PromptSections({ log }: { log: AIDebugLog }) {
  const request = log.request as {
    input?: { role?: string; content?: string }[];
    messages?: { role?: string; content?: string }[];
  };
  const messages = request.input || request.messages || [];
  return (
    <div className="ai-debug-payload">
      {messages.length > 0 ? (
        messages.map((message, index) => (
          <details key={`${message.role}-${index}`} open={index === 0}>
            <summary>{message.role === "system" ? "隱藏 System Prompt" : "實際 User Prompt / Context"}</summary>
            <pre>{message.content || ""}</pre>
          </details>
        ))
      ) : null}
      <details>
        <summary>完整外送 Request JSON</summary>
        <pre>{formatJSON(log.request)}</pre>
      </details>
      <details>
        <summary>Provider 回傳</summary>
        <pre>{formatJSON(log.response || { error: log.error || "無回傳資料" })}</pre>
      </details>
    </div>
  );
}

function EventEntry({ event }: { event: AITraderDebugEvent }) {
  return (
    <details className={`ai-debug-entry ai-debug-event ${event.status}`} key={event.id}>
      <summary>
        <span className="ai-debug-source">{event.title || event.event.replace(/_/g, " ")}</span>
        <span className="ai-debug-model">{event.phase || event.category} · {event.event}</span>
        <time>{new Date(event.createdAtIso).toLocaleString("zh-TW")}</time>
        <b>{event.status}</b>
      </summary>
      <div className="ai-debug-entry-meta">
        {event.accountId != null ? <span>Account ID：{event.accountId}</span> : <span>全域排程</span>}
        <span>階段：{event.phase || "—"}</span>
        <span>Run：{event.runKey || "—"}</span>
      </div>
      <div className="ai-debug-payload">
        <details open>
          <summary>完整事件資料</summary>
          <pre>{formatJSON(event.detail ?? { message: "此事件沒有附加資料" })}</pre>
        </details>
      </div>
    </details>
  );
}

export default function AIDebugObservatory() {
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);
  const [source, setSource] = useState("all");
  const [view, setView] = useState<"timeline" | "api">("timeline");
  const debugQ = useQuery({
    queryKey: ["ai-debug"],
    queryFn: () => aiApi.debug(),
    refetchInterval: open ? 3000 : false,
  });
  const toggleM = useMutation({
    mutationFn: (enabled: boolean) => aiApi.setDebug(enabled),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["ai-debug"] }),
  });
  const clearM = useMutation({
    mutationFn: () => aiApi.clearDebug(),
    onSuccess: () => qc.invalidateQueries({ queryKey: ["ai-debug"] }),
  });

  useEffect(() => {
    if (!open) return undefined;
    const onKey = (event: KeyboardEvent) => {
      if (event.key === "Escape") setOpen(false);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  const logs = debugQ.data?.logs || [];
  const events = debugQ.data?.events || [];
  const sources = useMemo(() => [...new Set(logs.map((log) => log.source))], [logs]);
  const visibleLogs = source === "all" ? logs : logs.filter((log) => log.source === source);
  const enabled = !!debugQ.data?.enabled;
  const usage = debugQ.data?.usageSummary;

  return (
    <>
      <button
        type="button"
        className={`ai-debug-orb${enabled ? " active" : ""}`}
        aria-label="開啟 AI 真視觀測鏡"
        title="查看交易員完整輪詢與 AI API Prompt"
        onClick={() => setOpen(true)}
      >
        <AppIcon name="compass" size={20} variant="nav" />
        {enabled ? <i /> : null}
      </button>

      {open ? (
        <div className="ai-debug-modal" role="dialog" aria-modal="true" aria-label="AI 真視觀測鏡">
          <button type="button" className="ai-debug-backdrop" aria-label="關閉真視觀測鏡" onClick={() => setOpen(false)} />
          <section className="ai-debug-panel">
            <header className="ai-debug-head">
              <span className="ai-debug-eye"><AppIcon name="compass" size={26} variant="nav" /></span>
              <div>
                <span>TRUE SIGHT · FULL LIFECYCLE</span>
                <strong>AI 真視觀測鏡</strong>
                <small>完整查看輪詢判斷、資料蒐集、分析、風控、交易、復盤與 API Prompt</small>
              </div>
              <button type="button" className="ai-debug-close" aria-label="關閉" onClick={() => setOpen(false)}>×</button>
            </header>

            <div className="ai-debug-controls">
              <div className="ai-debug-switch-copy">
                <strong>{enabled ? "偵錯觀測中" : "偵錯模式關閉"}</strong>
                <span>{enabled ? "每輪交易員生命週期與 AI API 呼叫都會完整寫入本機資料庫" : "開啟後才開始記錄，不會包含 API Key"}</span>
              </div>
              <button
                type="button"
                className={`ai-debug-switch${enabled ? " active" : ""}`}
                disabled={toggleM.isPending}
                onClick={() => toggleM.mutate(!enabled)}
              >
                <i />
                {enabled ? "ON" : "OFF"}
              </button>
              <select value={source} onChange={(event) => setSource(event.target.value)}>
                <option value="all">全部來源</option>
                {sources.map((item) => <option key={item} value={item}>{sourceLabel(item)}</option>)}
              </select>
              <button
                type="button"
                className="ai-debug-clear"
                disabled={(!logs.length && !events.length) || clearM.isPending}
                onClick={() => {
                  if (window.confirm("清除所有 AI 偵錯紀錄？這不會刪除聊天或交易員記憶。")) clearM.mutate();
                }}
              >
                清除紀錄
              </button>
            </div>

            <div className="ai-debug-summary">
              <span>{debugQ.data?.eventStored || 0} 筆生命週期事件</span>
              <span>{debugQ.data?.stored || 0} 筆 API 呼叫</span>
              <span>總 Token {formatTokens(usage?.totalTokens || 0)}</span>
              <span>Input {formatTokens(usage?.inputTokens || 0)}</span>
              <span>Output {formatTokens(usage?.outputTokens || 0)}</span>
              <strong>預估費用 {formatCost(usage?.estimatedCostUsd || 0)} USD</strong>
              {usage?.estimatedTokenLogs ? <span>{usage.estimatedTokenLogs} 筆 Token 為近似值</span> : null}
            </div>

            <div className="ai-debug-view-tabs">
              <button type="button" className={view === "timeline" ? "active" : ""} onClick={() => setView("timeline")}>交易員完整輪詢</button>
              <button type="button" className={view === "api" ? "active" : ""} onClick={() => setView("api")}>API Prompt 與回覆</button>
            </div>

            <div className="ai-debug-log">
              {view === "timeline" && !events.length ? (
                <div className="ai-debug-empty">
                  <strong>{enabled ? "觀測鏡已啟動，等待下一次交易員輪詢" : "先開啟偵錯模式"}</strong>
                  <p>每次排程檢查，即使跳過沒有交易，也會在這裡留下原因與完整資料。</p>
                </div>
              ) : null}
              {view === "timeline" ? events.map((event) => <EventEntry key={event.id} event={event} />) : null}
              {view === "api" && !visibleLogs.length ? (
                <div className="ai-debug-empty">
                  <strong>{enabled ? "等待下一次 AI API 呼叫" : "先開啟偵錯模式"}</strong>
                  <p>實際 System Prompt、User Prompt、Context 與 Provider 回覆會保留在這裡。</p>
                </div>
              ) : null}
              {view === "api" ? visibleLogs.map((log) => (
                <details className={`ai-debug-entry ${log.status}`} key={log.id}>
                  <summary>
                    <span className="ai-debug-source">{sourceLabel(log.source)}</span>
                    <span className="ai-debug-model">{log.provider} / {log.model || "default"}</span>
                    <time>{new Date(log.createdAtIso).toLocaleString("zh-TW")}</time>
                    <b>{log.status}</b>
                  </summary>
                  <div className="ai-debug-entry-meta">
                    <span>Endpoint：{log.endpoint || "—"}</span>
                    {log.accountId != null ? <span>Account ID：{log.accountId}</span> : null}
                    <span>
                      Token：{formatTokens(log.usage.inputTokens)} in + {formatTokens(log.usage.outputTokens)} out
                      {log.usage.estimated ? "（近似）" : ""}
                    </span>
                    <span>預估費用：{formatCost(log.usage.estimatedCostUsd)} USD</span>
                    <span>價格：{log.usage.pricingLabel}</span>
                    {log.error ? <span className="bad">Error：{log.error}</span> : null}
                  </div>
                  <PromptSections log={log} />
                </details>
              )) : null}
            </div>
          </section>
        </div>
      ) : null}
    </>
  );
}
