"use client";

import {
  Bot,
  CheckCircle2,
  Factory,
  MessageSquareText,
  Send,
  User,
  AlertCircle,
  BookOpen,
  Layers,
  Settings,
  Thermometer,
} from "lucide-react";

import type { FormEvent } from "react";
import { useCallback, useRef, useState } from "react";
import { ArtifactRenderer } from "@/components/artifacts/ArtifactRenderer";
import {
  createActionEvent,
  matchTextToAction,
  updateArtifactForAction,
} from "@/lib/artifacts/reducer";
import type { ArtifactAction, ArtifactActionEvent, InteractionArtifact } from "@/lib/artifacts/types";
import {
  buildVisibleActions,
  isNluResult,
  processVoiceInput,
} from "@/lib/nlu/pipeline";
import type { NluResult, PipelineSession } from "@/lib/nlu/types";
import { buildArtifactFromNlu } from "@/lib/artifacts/factory";
import {
  buildFalseWeldKnowledgeArtifact,
  buildDieMaterialAdjustArtifact,
  buildDieStatusOverviewArtifact,
} from "@/lib/artifacts/factory";



// ── 类型 ─────────────────────────────────────────────────────────────────────

type ChatMessage = {
  id: string;
  role: "user" | "assistant" | "system" | "error";
  text: string;
};

type FlowEvent = {
  id: string;
  title: string;
  detail: string;
  branch: string;
  kind: "ux" | "tech" | "action";
};

type ReferenceTab = {
  id: string;
  label: string;
  kind: "tool" | "knowledge" | "smalltalk";
  artifact?: InteractionArtifact;
  text?: string;
  branch: string;
};

function uid(prefix: string) {
  return `${prefix}_${Date.now()}_${Math.random().toString(16).slice(2)}`;
}

function isGuidedProcedureActive(artifact?: InteractionArtifact) {
  return artifact?.type === "guided_procedure" && artifact.status !== "success";
}

// ── 主组件 ───────────────────────────────────────────────────────────────────

export default function Home() {
  const [inputValue, setInputValue] = useState("");
  const [activeArtifact, setActiveArtifact] = useState<InteractionArtifact>();
  const [referenceTabs, setReferenceTabs] = useState<ReferenceTab[]>([]);
  const [activeReferenceId, setActiveReferenceId] = useState<string>();
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [, setFlowEvents] = useState<FlowEvent[]>([
    {
      id: uid("event"),
      title: "等待输入",
      detail: "当前没有激活调机流程，系统处于大流程 A：普通对话。",
      branch: "大流程 A · 普通对话",
      kind: "ux",
    },
  ]);

  // session_id 在页面生命周期内固定，重新刷新页面才重置
  const sessionId = useRef(uid("session")).current;
  const userId = useRef("user_001").current;

  const flowMode = isGuidedProcedureActive(activeArtifact) ? "B" : "A";
  const activeReference =
    referenceTabs.find((tab) => tab.id === activeReferenceId) ??
    referenceTabs[referenceTabs.length - 1];

  // 当前可见 Artifact 按钮（供 pipeline 阶段 1b 使用）
  const visibleActions = activeArtifact
    ? buildVisibleActions(activeArtifact.artifactId, activeArtifact.actions)
    : [];

  const pipelineSession = useCallback(
    (): PipelineSession => ({
      sessionId,
      status: activeArtifact?.status ?? "idle",
      visibleActions,
    }),
    [sessionId, activeArtifact, visibleActions],
  );

  // ── helpers ──────────────────────────────────────────────────────────────────

  function addMessage(role: ChatMessage["role"], text: string) {
    setMessages((items) => [...items, { id: uid("msg"), role, text }]);
  }

  function addFlowEvent(event: Omit<FlowEvent, "id">) {
    setFlowEvents((items) => [...items, { id: uid("event"), ...event }]);
  }

  // ── NLU 结果处理 ─────────────────────────────────────────────────────────────

  function handleNluResult(result: NluResult) {
    addFlowEvent({
      kind: "tech",
      branch: `${result.decisionGrade} · ${result.routeHint}`,
      title: `NLU：${result.domain} / ${result.intent}`,
      detail: `confidence=${result.confidence.toFixed(3)}; routeHint=${result.routeHint}; slots=${JSON.stringify(result.slots)}`,
    });

    if (isGuidedProcedureActive(activeArtifact)) {
      handleNluResultDuringProcedure(result);
      return;
    }

    // 等待补槽：只回复文字，不渲染 Artifact
    if (result.pendingSlots.length > 0) {
      addMessage("assistant", result.replyText);
      addFlowEvent({
        kind: "ux",
        branch: "ask_slot",
        title: "等待补槽",
        detail: `pending: ${result.pendingSlots.join(", ")}`,
      });
      return;
    }

    // ── LLM knowledge_search function call 命中 → 直接渲染知识卡片 ──────────
    if (result.knowledgeContent) {
      const knowledgeArtifact = buildFalseWeldKnowledgeArtifact();
      setActiveArtifact(knowledgeArtifact);
      setReferenceTabs([]);
      setActiveReferenceId(undefined);
      addMessage("assistant", result.replyText);
      addFlowEvent({
        kind: "ux",
        branch: "knowledge_query",
        title: `LLM 知识检索 → Artifact：knowledge_lesson`,
        detail: `doc=${result.knowledgeDocId ?? "llm_answer"}`,
      });
      return;
    }

    // 尝试从 NLU 结果构造 Artifact
    const artifact = buildArtifactFromNlu(result);
    if (artifact) {
      setActiveArtifact(artifact);
      setReferenceTabs([]);
      setActiveReferenceId(undefined);
      addMessage("assistant", result.replyText);
      addFlowEvent({
        kind: "ux",
        branch: result.routeHint,
        title: `主画布生成 Artifact：${artifact.type}`,
        detail: `intent=${result.intent}; artifact=${artifact.artifactId}`,
      });
      return;
    }

    // 无 Artifact：纯文字回复
    addMessage("assistant", result.replyText);
    addFlowEvent({
      kind: "ux",
      branch: result.routeHint,
      title: "AI 文字回复",
      detail: `decision=${result.rawDecision}`,
    });
  }

  function handleNluResultDuringProcedure(result: NluResult) {
    addMessage(
      "assistant",
      `当前处于调机流程中。${result.replyText}`,
    );
    addFlowEvent({
      kind: "ux",
      branch: result.routeHint,
      title: "临时回答（调机流程中）",
      detail: "大流程 B：结果进入参考区，不覆盖调机主卡。",
    });

    const tab: ReferenceTab = {
      id: uid("ref"),
      label: result.routeHint === "knowledge_query" ? "知识参考" : "工具结果",
      kind: result.routeHint === "knowledge_query" ? "knowledge" : "smalltalk",
      text: result.replyText,
      branch: result.routeHint,
    };
    setReferenceTabs((items) => [...items, tab]);
    setActiveReferenceId(tab.id);
  }

  // ── Artifact 动作处理 ────────────────────────────────────────────────────────

  function runArtifactAction(
    action: ArtifactAction,
    value?: unknown,
    source: ArtifactActionEvent["source"] = "click",
    transcript?: string,
  ) {
    if (!activeArtifact) return;

    const event = createActionEvent(activeArtifact.artifactId, action, source, value, transcript);
    addFlowEvent({
      kind: "action",
      branch: "命中当前组件动作",
      title: `ArtifactActionEvent：${action.actionId}`,
      detail: transcript ? `source=${source}; transcript=${transcript}` : `source=${source}`,
    });

    if (
      action.actionId === "artifact.confirm" &&
      ["parameter_change", "device_action"].includes(activeArtifact.type)
    ) {
      setActiveArtifact({
        ...activeArtifact,
        status: "running",
        actions: activeArtifact.actions.map((item) => ({ ...item, disabled: true })),
      } as InteractionArtifact);
      window.setTimeout(() => {
        setActiveArtifact((current) =>
          current ? updateArtifactForAction(current, event) : current,
        );
      }, 600);
      return;
    }

    setActiveArtifact((current) =>
      current ? updateArtifactForAction(current, event) : current,
    );
  }

  function runReferenceAction(tabId: string, action: ArtifactAction, value?: unknown) {
    const tab = referenceTabs.find((item) => item.id === tabId);
    if (!tab?.artifact) return;

    const event = createActionEvent(tab.artifact.artifactId, action, "click", value);
    setReferenceTabs((items) =>
      items.map((item) =>
        item.id === tabId && item.artifact
          ? { ...item, artifact: updateArtifactForAction(item.artifact, event) }
          : item,
      ),
    );
  }

  // ── 表单提交 ─────────────────────────────────────────────────────────────────

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    const text = inputValue.trim();
    if (!text || isLoading) return;

    addMessage("user", text);
    setInputValue("");
    setIsLoading(true);

    try {
      // 阶段 1b：先检查 Artifact 文本命中（本地，同步）
      if (activeArtifact) {
        const matchedAction = matchTextToAction(activeArtifact, text);
        if (matchedAction) {
          runArtifactAction(matchedAction, text, inferInputSource(text), text);
          addMessage("system", "命中当前组件动作，未进入新任务识别。");
          return;
        }
      }

      // pipeline（异步，调 intelligent_cabin）
      const result = await processVoiceInput(text, pipelineSession(), userId);

      if (isNluResult(result)) {
        handleNluResult(result);
        return;
      }

      // PipelineEvent 处理
      switch (result.type) {
        case "stop_action":
          setActiveArtifact((current) =>
            current ? { ...current, status: "paused" } : current,
          );
          addMessage("system", "已停止当前操作。");
          addFlowEvent({ kind: "action", branch: "停止词", title: "停止操作", detail: result.sourceText });
          break;

        case "voice_click_event": {
          if (activeArtifact) {
            const action = activeArtifact.actions.find(
              (a) => a.actionId === result.actionId,
            );
            if (action) {
              runArtifactAction(action, undefined, "voice", text);
            }
          }
          break;
        }

        case "slot_fill_event":
          addMessage("system", `Slot 填写：${result.value}`);
          // nluResult 已由 pipeline 内部更新服务端 session，Canvas 此处可选更新 UI
          if ("nluResult" in result) {
            handleNluResult((result as { nluResult: NluResult }).nluResult);
          }
          break;
      }
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      addMessage("error", `NLU 服务错误：${msg}`);
    } finally {
      setIsLoading(false);
    }
  }

  // ── 渲染 ─────────────────────────────────────────────────────────────────────

  return (
    <div className="min-h-screen w-full bg-[#f0f2f5] text-zinc-950">
      <header className="sticky top-0 z-20 flex min-h-16 items-center justify-between gap-4 border-b border-zinc-200 bg-white/95 px-5 backdrop-blur">
        <div className="flex items-center gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-950 text-white">
            <Factory className="h-5 w-5" />
          </div>
          <div>
            <h1 className="text-base font-extrabold">工业 AI 交互画布</h1>
            <p className="text-xs text-zinc-500">
              intelligent_cabin NLU · 大流程 {flowMode} · Artifact 状态机
            </p>
          </div>
        </div>
        <span
          className={`rounded-full px-3 py-1.5 text-xs font-bold ${
            flowMode === "A" ? "bg-blue-50 text-blue-700" : "bg-emerald-50 text-emerald-700"
          }`}
        >
          {flowMode === "A" ? "大流程 A · 普通对话" : "大流程 B · 调机流程中"}
        </span>
      </header>

      <main className="mx-auto grid w-full max-w-[1800px] gap-4 p-4 xl:grid-cols-[minmax(0,1fr)_420px]">
        <section className="grid min-w-0 gap-4">
          <section className="rounded-xl border border-zinc-200 bg-white p-4">
            <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
              <div>
                <div className="text-sm font-extrabold">
                  {flowMode === "A" ? "大流程 A · 普通对话" : "大流程 B · 调机流程中"}
                </div>
                <p className="mt-1 text-xs text-zinc-500">
                  {flowMode === "A"
                    ? "无激活调机流程：输入经过四阶段 Pipeline → intelligent_cabin NLU。"
                    : "GuidedProcedure 激活：短指令优先操作当前步骤，其他结果进入参考区。"}
                </p>
              </div>
            </div>

            {/* ── 演示工具栏（BERT 未训练弯管机语义时直接触发）── */}
            <div className="mb-3 rounded-lg border border-dashed border-zinc-300 bg-zinc-50/60 p-3">
              <p className="mb-2 text-[11px] font-semibold uppercase tracking-widest text-zinc-400">
                演示工具 · 直接触发（无需 NLU）
              </p>
              <div className="flex flex-wrap gap-2">
                <button
                  type="button"
                  onClick={() => setActiveArtifact(buildFalseWeldKnowledgeArtifact())}
                  className="inline-flex items-center gap-1.5 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-1.5 text-xs font-semibold text-emerald-700 hover:bg-emerald-100 transition-colors"
                >
                  <BookOpen className="h-3.5 w-3.5" />
                  虚焊报警怎么办
                </button>
                <button
                  type="button"
                  onClick={() => setActiveArtifact(buildDieMaterialAdjustArtifact())}
                  className="inline-flex items-center gap-1.5 rounded-lg border border-blue-200 bg-blue-50 px-3 py-1.5 text-xs font-semibold text-blue-700 hover:bg-blue-100 transition-colors"
                >
                  <Settings className="h-3.5 w-3.5" />
                  材料尺寸调模具伺服
                </button>
                <button
                  type="button"
                  onClick={() => setActiveArtifact(buildDieStatusOverviewArtifact())}
                  className="inline-flex items-center gap-1.5 rounded-lg border border-violet-200 bg-violet-50 px-3 py-1.5 text-xs font-semibold text-violet-700 hover:bg-violet-100 transition-colors"
                >
                  <Layers className="h-3.5 w-3.5" />
                  查看所有模具位置
                </button>
                <button
                  type="button"
                  onClick={() =>
                    setActiveArtifact(
                      buildArtifactFromNlu({
                        sessionId: "demo",
                        modelVersion: "demo",
                        domain: "cabin",
                        intent: "cabin_set_ac",
                        confidence: 0.99,
                        slots: { temperature: 22 },
                        routeHint: "tool_call",
                        decisionGrade: "high",
                        rawDecision: "execute",
                        replyText: "好的，空调调到22度。",
                        pendingSlots: [],
                        traceId: "demo",
                      }) ?? undefined
                    )
                  }
                  className="inline-flex items-center gap-1.5 rounded-lg border border-amber-200 bg-amber-50 px-3 py-1.5 text-xs font-semibold text-amber-700 hover:bg-amber-100 transition-colors"
                >
                  <Thermometer className="h-3.5 w-3.5" />
                  空调调温（NLU 演示）
                </button>
              </div>
            </div>

            <form onSubmit={handleSubmit}>
              <div className="flex items-center gap-2 rounded-lg border border-zinc-300 bg-white p-1.5 focus-within:border-zinc-950">
                <input
                  className="min-w-0 flex-1 bg-transparent px-3 py-2 text-sm outline-none placeholder:text-zinc-400"
                  onChange={(e) => setInputValue(e.target.value)}
                  placeholder={
                    flowMode === "B"
                      ? "输入：已完成 / 压力是 0.32 / 或新的问题"
                      : "输入工业设备问题或控制请求（接 intelligent_cabin NLU）"
                  }
                  value={inputValue}
                  disabled={isLoading}
                />
                <button
                  className="inline-flex h-9 w-9 items-center justify-center rounded-md bg-zinc-950 text-white hover:bg-zinc-800 disabled:opacity-40"
                  disabled={!inputValue.trim() || isLoading}
                  type="submit"
                >
                  {isLoading ? (
                    <svg className="h-4 w-4 animate-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v4m0 8v4M4 12h4m8 0h4" />
                    </svg>
                  ) : (
                    <Send className="h-4 w-4" />
                  )}
                </button>
              </div>
            </form>
          </section>

          <section className="min-w-0 rounded-xl border border-zinc-200 bg-white p-5">
            <div className="min-w-0">
              {activeArtifact ? (
                <ArtifactRenderer artifact={activeArtifact} onAction={runArtifactAction} />
              ) : (
                <EmptyCanvas />
              )}
            </div>
          </section>
        </section>

        <aside className="min-w-0">
          <section className="flex min-h-[360px] flex-col rounded-xl border border-zinc-200 bg-white">
            <div className="border-b border-zinc-100 p-4">
              <div className="flex items-center gap-2 text-sm font-bold">
                <MessageSquareText className="h-4 w-4" />
                {flowMode === "B" ? "参考 Tab / 临时回答" : "对话记录"}
              </div>
              <p className="mt-1 text-xs leading-5 text-zinc-500">
                {flowMode === "B"
                  ? "调机流程中，新工具/知识不会覆盖主卡。"
                  : "NLU 通过 intelligent_cabin 处理，结果显示在此。"}
              </p>
            </div>

            {flowMode === "B" && referenceTabs.length > 0 ? (
              <div className="min-h-0 flex-1 overflow-y-auto p-4">
                <div className="mb-3 flex flex-wrap gap-2">
                  {referenceTabs.map((tab) => (
                    <button
                      type="button"
                      onClick={() => setActiveReferenceId(tab.id)}
                      className={`rounded-full px-3 py-1.5 text-xs font-bold ${
                        activeReference?.id === tab.id
                          ? "bg-zinc-950 text-white"
                          : "bg-zinc-100 text-zinc-600"
                      }`}
                      key={tab.id}
                    >
                      {tab.label}
                    </button>
                  ))}
                </div>
                {activeReference?.artifact ? (
                  <ArtifactRenderer
                    artifact={activeReference.artifact}
                    onAction={(action, value) => runReferenceAction(activeReference.id, action, value)}
                  />
                ) : (
                  <div className="rounded-lg bg-zinc-50 p-4 text-sm leading-6 text-zinc-600">
                    {activeReference?.text}
                  </div>
                )}
              </div>
            ) : (
              <MessageList messages={messages} />
            )}
          </section>
        </aside>
      </main>
    </div>
  );
}

// ── 工具函数 ─────────────────────────────────────────────────────────────────

function inferInputSource(text: string): ArtifactActionEvent["source"] {
  return /^(语音|voice|asr)[:：]/i.test(text.trim()) ? "voice" : "text";
}

// ── 纯展示组件 ───────────────────────────────────────────────────────────────

function MessageList({ messages }: { messages: ChatMessage[] }) {
  return (
    <div className="min-h-0 flex-1 overflow-y-auto p-4">
      <div className="space-y-3">
        {messages.length === 0 && (
          <div className="rounded-lg border border-dashed border-zinc-200 p-4 text-sm leading-6 text-zinc-500">
            输入任意文字，经 Pipeline → intelligent_cabin NLU 处理后显示结果。
            服务地址：<code className="rounded bg-zinc-100 px-1">NEXT_PUBLIC_NLU_BASE_URL</code>（默认 localhost:8000）
          </div>
        )}
        {messages.map((message) => (
          <div
            className={`flex gap-2 ${message.role === "user" ? "justify-end" : "justify-start"}`}
            key={message.id}
          >
            <div
              className={`max-w-[92%] rounded-lg px-3 py-2 text-sm leading-6 ${
                message.role === "user"
                  ? "bg-zinc-950 text-white"
                  : message.role === "system"
                    ? "bg-blue-50 text-blue-700"
                    : message.role === "error"
                      ? "bg-red-50 text-red-700"
                      : "bg-zinc-100 text-zinc-800"
              }`}
            >
              <div className="mb-1 flex items-center gap-1 text-[11px] opacity-70">
                {message.role === "user" ? (
                  <User className="h-3 w-3" />
                ) : message.role === "error" ? (
                  <AlertCircle className="h-3 w-3" />
                ) : (
                  <Bot className="h-3 w-3" />
                )}
                {message.role === "user"
                  ? "用户"
                  : message.role === "system"
                    ? "系统"
                    : message.role === "error"
                      ? "错误"
                      : "AI"}
              </div>
              {message.text}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function EmptyCanvas() {
  return (
    <div className="flex min-h-[520px] items-center justify-center">
      <div className="max-w-xl text-center">
        <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-xl bg-zinc-50 text-zinc-500">
          <CheckCircle2 className="h-8 w-8" />
        </div>
        <h2 className="mt-5 text-2xl font-semibold">等待 intelligent_cabin NLU 响应</h2>
        <p className="mt-3 text-sm leading-6 text-zinc-500">
          输入会经过四阶段处理链路：停止词 → UI 语音点击 → 槽位填写 → BERT NLU。
          NLU 服务需在 <code className="rounded bg-zinc-100 px-1">NEXT_PUBLIC_NLU_BASE_URL</code>（默认 localhost:8000）运行。
        </p>
      </div>
    </div>
  );
}
