"use client";

import { useEffect, useRef, useState } from "react";
import {
  Braces,
  Bot,
  Brain,
  Database,
  Loader2,
  MessageSquareText,
  Save,
  Sparkles,
  Wrench,
} from "lucide-react";

import { DebugDrawer } from "@/components/assistant-editor/debug-preview";
import {
  DynamicVariableEditorHint,
  DynamicVariablesSection,
} from "@/components/assistant-editor/dynamic-variables";
import {
  AssistantIdentity,
  EditableTitle,
  EditorBackButton,
  KnowledgeRetrievalConfigDialog,
  ResourceSelectField,
  RuntimeModeSelector,
  TextAreaField,
  ToolPicker,
} from "@/components/assistant-editor/editor-controls";
import type { AssistantForm } from "@/components/assistant-editor/types";
import { SectionCard } from "@/components/editor/section-card";
import { VisionConfigSection } from "@/components/editor/vision-config-section";
import { TurnConfigEditor } from "@/components/turn-config-editor";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import type {
  DynamicVariableDefinition,
  StartupConfig,
  Tool,
} from "@/lib/api";

type ResourceOption = { value: string; label: string };
type PromptOpeningMode = StartupConfig["openingMode"];
type PromptEntryMode = StartupConfig["entryMode"];

const OPENING_MODE_OPTIONS: Array<{
  value: PromptOpeningMode;
  label: string;
  description: string;
}> = [
  {
    value: "interruptible",
    label: "可打断",
    description: "用户说话、发文字或图片时立即结束开场白，并保留这次输入。",
  },
  {
    value: "playback",
    label: "播完继续",
    description: "开场白播放期间关闭输入，实际播放完成后进入 Agent。",
  },
  {
    value: "confirmation",
    label: "需要弹窗确认继续",
    description: "关闭对话输入并显示弹窗，用户确认后立即进入 Agent。",
  },
];

const ENTRY_MODE_OPTIONS: Array<{
  value: PromptEntryMode;
  label: string;
}> = [
  { value: "wait_user", label: "等待下一轮用户输入" },
  { value: "generate", label: "进入后立即回复" },
];

const promptSections = [
  { id: "conversation", label: "对话内容" },
  { id: "models", label: "模型与语音" },
  { id: "capabilities", label: "知识与工具" },
  { id: "interaction", label: "交互策略" },
  { id: "variables", label: "动态变量" },
] as const;

type PromptSectionId = (typeof promptSections)[number]["id"];

type PromptEditorProps = {
  assistantId: string | null;
  form: AssistantForm;
  dynamicVariableDefinitions: Record<string, DynamicVariableDefinition>;
  saving: boolean;
  dirty: boolean;
  saveError: string | null;
  llmOptions: ResourceOption[];
  asrOptions: ResourceOption[];
  ttsOptions: ResourceOption[];
  realtimeOptions: ResourceOption[];
  visionModelOptions: ResourceOption[];
  knowledgeOptions: ResourceOption[];
  tools: Tool[];
  onBack: () => void;
  onSave: () => void;
  updateForm: <K extends keyof AssistantForm>(
    key: K,
    value: AssistantForm[K],
  ) => void;
  handlePromptVisionEnabledChange: (enabled: boolean) => void;
  handlePromptModelChange: (value: string) => void;
};

export function PromptEditor({
  assistantId,
  form,
  dynamicVariableDefinitions,
  saving,
  dirty,
  saveError,
  llmOptions,
  asrOptions,
  ttsOptions,
  realtimeOptions,
  visionModelOptions,
  knowledgeOptions: kbOptions,
  tools,
  onBack,
  onSave,
  updateForm,
  handlePromptVisionEnabledChange,
  handlePromptModelChange,
}: PromptEditorProps) {
  const openingMessage = form.startup.openingMessage;
  const openingMode = form.startup.openingMode;
  const openingModeDescription = OPENING_MODE_OPTIONS.find(
    (option) => option.value === openingMode,
  )?.description;
  const scrollContainerRef = useRef<HTMLDivElement>(null);
  const sectionRefs = useRef<Record<PromptSectionId, HTMLElement | null>>({
    conversation: null,
    models: null,
    capabilities: null,
    interaction: null,
    variables: null,
  });
  const selectedAnchorRef = useRef<PromptSectionId | null>(null);
  const [activeSection, setActiveSection] =
    useState<PromptSectionId>("conversation");

  useEffect(() => {
    const container = scrollContainerRef.current;
    if (!container) return;
    const scrollContainer: HTMLDivElement = container;

    let animationFrame = 0;

    function updateActiveSection() {
      if (selectedAnchorRef.current) {
        setActiveSection(selectedAnchorRef.current);
        return;
      }

      const containerTop = scrollContainer.getBoundingClientRect().top;
      const activationLine = containerTop + 24;
      let nextSection: PromptSectionId = promptSections[0].id;

      for (const section of promptSections) {
        const element = sectionRefs.current[section.id];
        if (element && element.getBoundingClientRect().top <= activationLine) {
          nextSection = section.id;
        }
      }

      const reachedBottom =
        scrollContainer.scrollHeight > scrollContainer.clientHeight + 8 &&
        scrollContainer.scrollHeight -
          scrollContainer.scrollTop -
          scrollContainer.clientHeight <
          8;
      if (reachedBottom) {
        nextSection = promptSections[promptSections.length - 1].id;
      }

      setActiveSection((current) =>
        current === nextSection ? current : nextSection,
      );
    }

    function scheduleUpdate() {
      window.cancelAnimationFrame(animationFrame);
      animationFrame = window.requestAnimationFrame(updateActiveSection);
    }

    function releaseSelectedAnchor() {
      selectedAnchorRef.current = null;
      scheduleUpdate();
    }

    scheduleUpdate();
    scrollContainer.addEventListener("scroll", scheduleUpdate, {
      passive: true,
    });
    scrollContainer.addEventListener("wheel", releaseSelectedAnchor, {
      passive: true,
    });
    scrollContainer.addEventListener("touchstart", releaseSelectedAnchor, {
      passive: true,
    });
    window.addEventListener("resize", scheduleUpdate);

    return () => {
      window.cancelAnimationFrame(animationFrame);
      scrollContainer.removeEventListener("scroll", scheduleUpdate);
      scrollContainer.removeEventListener("wheel", releaseSelectedAnchor);
      scrollContainer.removeEventListener("touchstart", releaseSelectedAnchor);
      window.removeEventListener("resize", scheduleUpdate);
    };
  }, [form.runtimeMode]);

  function scrollToSection(sectionId: PromptSectionId) {
    const container = scrollContainerRef.current;
    const section = sectionRefs.current[sectionId];
    if (!container || !section) return;

    const containerTop = container.getBoundingClientRect().top;
    const sectionTop = section.getBoundingClientRect().top;

    selectedAnchorRef.current = sectionId;
    setActiveSection(sectionId);
    container.scrollTo({
      top: container.scrollTop + sectionTop - containerTop,
      behavior: "smooth",
    });
  }

  function setOpeningMode(nextMode: PromptOpeningMode) {
    updateForm("startup", {
      ...form.startup,
      openingMode: nextMode,
      openingMessage: nextMode === "confirmation"
        ? {
            title: openingMessage?.title ?? "重要提示",
            message: openingMessage?.message ?? "请确认已阅读以上信息。",
            confirmLabel: openingMessage?.confirmLabel ?? "确认",
          }
        : null,
    });
  }

  function updateOpeningMessage(
    patch: Partial<NonNullable<typeof openingMessage>>,
  ) {
    if (!openingMessage) return;
    updateForm("startup", {
      ...form.startup,
      openingMessage: { ...openingMessage, ...patch },
    });
  }

  return (
    <div className="-mt-6 flex h-full flex-col gap-4 overflow-hidden bg-background">
      <div className="flex shrink-0 items-center justify-between gap-6 border-b border-hairline pb-3 pt-1">
        <div className="flex min-w-0 items-center gap-2">
          <EditorBackButton onClick={onBack} />
          <EditableTitle
            value={form.name}
            onChange={(value) => updateForm("name", value)}
          />
          <AssistantIdentity assistantId={assistantId} />
        </div>

        <div className="flex shrink-0 gap-2">
          {saveError && (
            <span className="self-center text-xs text-destructive">
              {saveError}
            </span>
          )}
          <Button
            className="gap-2"
            disabled={saving || !dirty || !form.name.trim()}
            onClick={() => onSave()}
          >
            {saving ? (
              <Loader2 size={16} className="animate-spin" />
            ) : (
              <Save size={16} />
            )}
            保存
          </Button>
        </div>
      </div>

      <div className="flex min-h-0 flex-1 gap-4">
        <div className="flex min-h-0 min-w-0 flex-1 flex-col gap-3">
          <nav
            aria-label="提示词配置分区"
            className="shrink-0 overflow-x-auto overscroll-none"
          >
            <div className="grid min-w-[28rem] grid-cols-5 border-b border-hairline">
              {promptSections.map((section) => {
                const active = activeSection === section.id;

                return (
                  <button
                    key={section.id}
                    type="button"
                    aria-current={active ? "location" : undefined}
                    onClick={() => scrollToSection(section.id)}
                    className={[
                      "-mb-px whitespace-nowrap border-b-2 px-2 py-2.5 text-center text-xs transition-colors sm:px-3 sm:text-sm",
                      active
                        ? "border-primary text-foreground"
                        : "border-transparent text-muted-foreground hover:bg-surface-strong/50 hover:text-foreground",
                    ].join(" ")}
                  >
                    {section.label}
                  </button>
                );
              })}
            </div>
          </nav>

          <div
            ref={scrollContainerRef}
            className="scrollbar-subtle min-h-0 min-w-0 flex-1 space-y-3 overflow-y-auto overscroll-none bg-background pr-1"
          >
            <section
              ref={(element) => {
                sectionRefs.current.conversation = element;
              }}
              className="scroll-mt-3 space-y-3"
            >
              <SectionCard
                icon={<MessageSquareText size={15} />}
                title="提示词"
                description="描述助手的角色、能力和回答要求"
              >
                <TextAreaField
                  value={form.prompt}
                  onChange={(value) => updateForm("prompt", value)}
                  placeholder="请输入提示词，描述助手的角色、能力和回答要求"
                  rows={8}
                />
                <DynamicVariableEditorHint
                  count={Object.keys(dynamicVariableDefinitions).length}
                  onOpen={() => scrollToSection("variables")}
                />
              </SectionCard>

              <SectionCard
                icon={<Bot size={15} />}
                title="开场白"
                description="助手与用户首次对话时的开场语"
              >
                <TextAreaField
                  value={form.greeting}
                  onChange={(value) => updateForm("greeting", value)}
                  placeholder="请输入助手开场白"
                />
                <DynamicVariableEditorHint
                  count={Object.keys(dynamicVariableDefinitions).length}
                  onOpen={() => scrollToSection("variables")}
                />
                {form.runtimeMode === "pipeline" && (
                  <div className="mt-4 space-y-3 border-t border-hairline pt-4">
                    <div>
                      <div className="mb-1.5 text-sm font-medium text-foreground">
                        开场白继续方式
                      </div>
                      <Select
                        value={openingMode}
                        onValueChange={(value: PromptOpeningMode) =>
                          setOpeningMode(value)
                        }
                      >
                        <SelectTrigger className="w-full border-hairline-strong bg-background text-foreground">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          {OPENING_MODE_OPTIONS.map((option) => (
                            <SelectItem key={option.value} value={option.value}>
                              {option.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <p className="mt-1.5 text-xs leading-5 text-muted-foreground">
                        {openingModeDescription}
                      </p>
                    </div>

                    {openingMode === "confirmation" && openingMessage && (
                      <div className="space-y-3 rounded-xl border border-hairline bg-canvas-soft p-4">
                        <label className="block">
                          <span className="mb-1.5 block text-sm font-medium text-foreground">
                            弹窗标题
                          </span>
                          <Input
                            value={openingMessage.title}
                            onChange={(event) =>
                              updateOpeningMessage({ title: event.target.value })
                            }
                            placeholder="重要提示"
                            className="border-hairline-strong bg-background"
                          />
                        </label>
                        <TextAreaField
                          label="重要信息"
                          value={openingMessage.message}
                          onChange={(message) =>
                            updateOpeningMessage({ message })
                          }
                          placeholder="请输入需要用户确认的重要信息"
                          rows={4}
                        />
                        <label className="block">
                          <span className="mb-1.5 block text-sm font-medium text-foreground">
                            确认按钮
                          </span>
                          <Input
                            value={openingMessage.confirmLabel}
                            onChange={(event) =>
                              updateOpeningMessage({
                                confirmLabel: event.target.value,
                              })
                            }
                            placeholder="确认"
                            className="border-hairline-strong bg-background"
                          />
                        </label>
                        <p className="text-xs leading-5 text-muted-foreground">
                          确认前关闭语音、文字和图片输入；确认后立即停止剩余开场白并进入 Agent。
                        </p>
                      </div>
                    )}

                    <div className="border-t border-hairline pt-3">
                      <div className="mb-1.5 text-sm font-medium text-foreground">
                        Agent 进入行为
                      </div>
                      <Select
                        value={form.startup.entryMode}
                        onValueChange={(entryMode: PromptEntryMode) =>
                          updateForm("startup", {
                            ...form.startup,
                            entryMode,
                          })
                        }
                      >
                        <SelectTrigger className="w-full border-hairline-strong bg-background text-foreground">
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          {ENTRY_MODE_OPTIONS.map((option) => (
                            <SelectItem key={option.value} value={option.value}>
                              {option.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <p className="mt-1.5 text-xs leading-5 text-muted-foreground">
                        该设置仅控制开场阶段正常完成后的 Agent 首轮行为。
                      </p>
                    </div>
                  </div>
                )}
              </SectionCard>
            </section>

            <section
              ref={(element) => {
                sectionRefs.current.models = element;
              }}
              className="scroll-mt-3 space-y-3"
            >
              <SectionCard
                icon={<Brain size={15} />}
                title="模型与语音"
                description={
                  form.runtimeMode === "pipeline"
                    ? "选择运行方式，以及大语言模型、语音识别与语音合成资源"
                    : "选择运行方式；Realtime 模型内置语音识别与语音合成"
                }
              >
                <RuntimeModeSelector
                  value={form.runtimeMode}
                  onChange={(runtimeMode) => {
                    updateForm("runtimeMode", runtimeMode);
                    if (
                      runtimeMode === "realtime" &&
                      (form.startup.actions.length ||
                        form.startup.openingMode !== "interruptible" ||
                        form.startup.entryMode !== "wait_user" ||
                        form.startup.openingMessage)
                    ) {
                      updateForm("startup", {
                        executionMode: "sequential",
                        openingMode: "interruptible",
                        entryMode: "wait_user",
                        actions: [],
                        openingMessage: null,
                      });
                    }
                  }}
                />

                {form.runtimeMode === "pipeline" ? (
                  <>
                    <ResourceSelectField
                      label="大语言模型"
                      value={form.model}
                      onChange={handlePromptModelChange}
                      options={llmOptions}
                      noneLabel="无"
                    />
                    <ResourceSelectField
                      label="语音识别"
                      value={form.asr}
                      onChange={(value) => updateForm("asr", value)}
                      options={asrOptions}
                      noneLabel="无"
                    />
                    <ResourceSelectField
                      label="语音合成"
                      value={form.voice}
                      onChange={(value) => updateForm("voice", value)}
                      options={ttsOptions}
                      noneLabel="无"
                    />
                  </>
                ) : (
                  <ResourceSelectField
                    label="Realtime 模型"
                    value={form.realtimeModel}
                    onChange={(value) => updateForm("realtimeModel", value)}
                    options={realtimeOptions}
                    noneLabel="无"
                  />
                )}
              </SectionCard>
            </section>

            <section
              ref={(element) => {
                sectionRefs.current.capabilities = element;
              }}
              className="scroll-mt-3 space-y-3"
            >
              {form.runtimeMode === "pipeline" && (
                <VisionConfigSection
                  description="配置提示词助手是否可以按需理解用户摄像头画面"
                  hint="开启后，助手会获得读取当前视频画面的工具。选择「模型自己」时，大语言模型必须支持图片输入。"
                  enabled={form.visionEnabled}
                  modelResourceId={form.visionModelResourceId}
                  mainModelResourceId={form.model}
                  modelOptions={visionModelOptions}
                  onEnabledChange={handlePromptVisionEnabledChange}
                  onModelResourceIdChange={(value) =>
                    updateForm("visionModelResourceId", value)
                  }
                />
              )}

              {form.runtimeMode === "pipeline" && (
                <SectionCard
                  icon={<Database size={15} />}
                  title="知识库配置"
                  description="选择助手回答时可检索的业务知识来源"
                >
                  <div className="flex items-center gap-1.5">
                    <span className="text-sm font-medium text-foreground">
                      知识库选择
                    </span>
                    <KnowledgeRetrievalConfigDialog
                      disabled={!form.knowledgeBase}
                      value={form.knowledgeRetrievalConfig}
                      onChange={(config) =>
                        updateForm("knowledgeRetrievalConfig", config)
                      }
                    />
                  </div>
                  <ResourceSelectField
                    value={form.knowledgeBase}
                    onChange={(value) => updateForm("knowledgeBase", value)}
                    options={kbOptions}
                    noneLabel="无"
                  />
                </SectionCard>
              )}

              <SectionCard
                icon={<Wrench size={15} />}
                title="工具"
                description="配置该提示词助手可以调用的工具"
              >
                <ToolPicker
                  tools={tools.filter((tool) => tool.status === "active")}
                  selectedIds={form.toolIds}
                  onChange={(toolIds) => updateForm("toolIds", toolIds)}
                />
              </SectionCard>
            </section>

            <section
              ref={(element) => {
                sectionRefs.current.interaction = element;
              }}
              className="scroll-mt-3 space-y-3"
            >
              <SectionCard
                icon={<Sparkles size={15} />}
                title="交互策略"
                description="设置实时视频对话时的交互体验"
              >
                {form.runtimeMode === "pipeline" ? (
                  <TurnConfigEditor
                    enabled={form.enableInterrupt}
                    config={form.turnConfig}
                    onEnabledChange={(checked) =>
                      updateForm("enableInterrupt", checked)
                    }
                    onConfigChange={(config) =>
                      updateForm("turnConfig", config)
                    }
                  />
                ) : (
                  <p className="text-sm text-muted-foreground">
                    高级抢话与轮次检测当前仅支持 Pipeline 模式。
                  </p>
                )}
              </SectionCard>
            </section>

            <section
              ref={(element) => {
                sectionRefs.current.variables = element;
              }}
              className="scroll-mt-3 space-y-3"
            >
              <SectionCard
                icon={<Braces size={15} />}
                title="动态变量"
                description="编辑提示词和开场白中引用的自定义变量"
              >
                <DynamicVariablesSection
                  definitions={dynamicVariableDefinitions}
                  onChange={(dynamicVariableDefinitions) =>
                    updateForm(
                      "dynamicVariableDefinitions",
                      dynamicVariableDefinitions,
                    )
                  }
                />
              </SectionCard>
            </section>
          </div>
        </div>

        <DebugDrawer
          assistantId={assistantId}
          hasUnsavedChanges={dirty}
          vision={form.visionEnabled}
          dynamicVariablesEnabled
          dynamicVariableDefinitions={dynamicVariableDefinitions}
        />
      </div>
    </div>
  );
}
