"use client";

/**
 * 测试用例管理：
 * - 列表页：Test Suite 一级容器
 * - 详情页：左列表 + 右编辑器（固定脚本 / 用户模拟，只编辑不运行）
 */

import {
  ChevronLeft,
  Copy,
  Loader2,
  MoreHorizontal,
  Pencil,
  Plus,
  Rocket,
  Save,
  Trash2,
  X,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";

import {
  AssistantIdentity,
  EditableTitle,
  EditorBackButton,
} from "@/components/assistant-editor/editor-controls";
import {
  ListPageLayout,
  ListPageSection,
} from "@/components/layout/list-page-layout";
import { TopbarPortal } from "@/components/layout/topbar-portal";
import { InputModePicker } from "@/components/test-cases/input-mode-picker";
import {
  NextReplyEditorBody,
  type CaseEditorDraft,
} from "@/components/test-cases/next-reply-editor";
import { SuiteCaseList } from "@/components/test-cases/suite-case-list";
import { Button } from "@/components/ui/button";
import { DataList } from "@/components/ui/data-list";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { ListToolbar } from "@/components/ui/list-toolbar";
import { SearchInput } from "@/components/ui/search-input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  cloneOverallCriteria,
  cloneTurns,
  createEmptyFixedInputTurn,
  createTestCase,
  createTestSuite,
  DEFAULT_INPUT_MODE,
  duplicateTestCase,
  duplicateTestSuite,
  getTestCaseValidationMessage,
  getTestSuite,
  listTestCases,
  listTestSuites,
  normalizeOverallCriteria,
  removeTestCase,
  removeTestCases,
  removeTestSuite,
  reorderTestCases,
  suiteCaseStats,
  TEST_CASE_INPUT_MODE_LABEL,
  TEST_CASE_INPUT_MODE_SHORT_LABEL,
  updateTestCase,
  updateTestSuite,
  type TestCase,
  type TestCaseInputMode,
  type TestSuite,
} from "@/data/test-suites";
import { assistantsApi, type Assistant } from "@/lib/api";

// 路由驱动:
// /test/cases → list
// /test/cases/new → create suite
// /test/cases/[id] → suite detail (cases)
export type TestCasesPageProps =
  | { mode: "list" }
  | { mode: "create" }
  | { mode: "detail"; suiteId: string; initialCaseId?: string };

export function TestCasesPage(props: TestCasesPageProps) {
  if (props.mode === "list") return <SuiteListView />;
  if (props.mode === "create") return <SuiteCreateView />;
  return (
    <SuiteDetailView
      key={`${props.suiteId}:${props.initialCaseId ?? ""}`}
      suiteId={props.suiteId}
      initialCaseId={props.initialCaseId}
    />
  );
}

// ─── Suite 列表 ──────────────────────────────────────────────────────────────

function SuiteListView() {
  const router = useRouter();
  const [suites, setSuites] = useState<TestSuite[]>(() => listTestSuites());
  const [search, setSearch] = useState("");
  const [currentPage, setCurrentPage] = useState(1);
  const [deletingId, setDeletingId] = useState<string | null>(null);

  const filtered = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    return suites.filter((suite) => {
      if (!keyword) return true;
      return [suite.name, suite.assistantName, suite.id]
        .join(" ")
        .toLowerCase()
        .includes(keyword);
    });
  }, [suites, search]);

  const pageSize = 5;
  const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
  const safeCurrentPage = Math.min(currentPage, totalPages);
  const pageStart = (safeCurrentPage - 1) * pageSize;
  const pageEnd = pageStart + pageSize;
  const paginated = filtered.slice(pageStart, pageEnd);

  function openSuite(suite: TestSuite) {
    router.push(`/test/cases/${suite.id}`);
  }

  function duplicateSuite(suite: TestSuite) {
    const copied = duplicateTestSuite(suite.id);
    if (!copied) return;
    setSuites(listTestSuites());
  }

  function removeSuite(suite: TestSuite) {
    if (
      !window.confirm(
        `确定删除测试集“${suite.name}”及其全部测试用例吗？`,
      )
    ) {
      return;
    }
    setDeletingId(suite.id);
    removeTestSuite(suite.id);
    setSuites(listTestSuites());
    setDeletingId(null);
  }

  return (
    <ListPageLayout
      title="测试用例"
      description="管理用于助手调试的固定输入测试场景。"
      action={
        <Button
          className="w-full shrink-0 gap-2 sm:w-auto"
          onClick={() => router.push("/test/cases/new")}
        >
          <Plus size={16} />
          新建测试集
        </Button>
      }
    >
      <ListPageSection>
        <ListToolbar
          className="lg:justify-end"
          search={
            <SearchInput
              value={search}
              onChange={(value) => {
                setSearch(value);
                setCurrentPage(1);
              }}
              placeholder="搜索测试集..."
              className="lg:w-[320px]"
            />
          }
        />

        <DataList<TestSuite>
          rows={paginated}
          rowKey={(suite) => suite.id}
          onRowClick={openSuite}
          empty={{
            title: suites.length === 0 ? "暂无测试集" : "未找到匹配的测试集",
            description:
              suites.length === 0
                ? "点击右上角「新建测试集」开始。"
                : "请调整关键词后再试。",
          }}
          pagination={{
            page: safeCurrentPage,
            totalPages,
            onPageChange: setCurrentPage,
            summary:
              filtered.length === 0
                ? "没有数据"
                : `显示 ${pageStart + 1}-${Math.min(pageEnd, filtered.length)} / 共 ${filtered.length} 个测试集`,
          }}
          columns={[
            {
              key: "name",
              header: "测试集名称",
              width: "md:w-[320px]",
              cell: (suite) => (
                <>
                  <div className="truncate font-medium text-foreground">
                    {suite.name}
                  </div>
                  <div className="mt-1 truncate font-mono text-xs text-muted-soft">
                    {suite.id}
                  </div>
                </>
              ),
            },
            {
              key: "assistant",
              header: "关联助手",
              width: "md:w-[160px]",
              cellClassName: "text-muted-foreground",
              cell: (suite) => suite.assistantName || "—",
            },
            {
              key: "caseCount",
              header: "用例数",
              width: "md:w-[96px]",
              cellClassName: "tabular-nums text-muted-foreground",
              cell: (suite) => suiteCaseStats(suite.id).total,
            },
            {
              key: "actions",
              header: "操作",
              align: "right",
              cell: (suite) => (
                <div
                  className="flex justify-end gap-2"
                  onClick={(event) => event.stopPropagation()}
                  onPointerDown={(event) => event.stopPropagation()}
                >
                  <Button
                    variant="outline"
                    size="sm"
                    className="gap-1.5 border-hairline-strong text-xs text-muted-foreground hover:text-foreground"
                    onClick={(event) => {
                      event.stopPropagation();
                      openSuite(suite);
                    }}
                  >
                    <Pencil size={14} />
                    编辑
                  </Button>
                  <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                      <Button
                        variant="outline"
                        size="icon-sm"
                        className="border-hairline-strong text-muted-foreground hover:text-foreground"
                        aria-label={`${suite.name} 更多操作`}
                        onClick={(event) => event.stopPropagation()}
                      >
                        <MoreHorizontal size={15} />
                      </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent
                      align="end"
                      className="w-32 min-w-32 rounded-xl border border-hairline bg-popover p-1"
                    >
                      <DropdownMenuItem
                        className="rounded-lg"
                        onSelect={() => duplicateSuite(suite)}
                      >
                        <Copy size={14} />
                        复制
                      </DropdownMenuItem>
                      <DropdownMenuItem
                        variant="destructive"
                        className="rounded-lg"
                        disabled={deletingId === suite.id}
                        onSelect={(event) => {
                          event.preventDefault();
                          window.setTimeout(() => removeSuite(suite), 0);
                        }}
                      >
                        {deletingId === suite.id ? (
                          <Loader2 size={14} className="animate-spin" />
                        ) : (
                          <Trash2 size={14} />
                        )}
                        删除
                      </DropdownMenuItem>
                    </DropdownMenuContent>
                  </DropdownMenu>
                </div>
              ),
            },
          ]}
        />
      </ListPageSection>
    </ListPageLayout>
  );
}

// ─── 新建测试集 ──────────────────────────────────────────────────────────────

function SuiteCreateView() {
  const router = useRouter();
  const [assistants, setAssistants] = useState<Assistant[]>([]);
  const [loadingAssistants, setLoadingAssistants] = useState(true);
  const [name, setName] = useState("");
  const [assistantName, setAssistantName] = useState("");
  const [creating, setCreating] = useState(false);

  useEffect(() => {
    void (async () => {
      try {
        const list = await assistantsApi.list();
        setAssistants(list);
        if (list[0]) setAssistantName(list[0].name);
      } catch {
        setAssistantName("视频快处助手");
      } finally {
        setLoadingAssistants(false);
      }
    })();
  }, []);

  function confirmCreate() {
    if (!name.trim() || creating) return;
    setCreating(true);
    const saved = createTestSuite({
      name,
      description: "",
      assistantName,
    });
    router.push(`/test/cases/${saved.id}`);
  }

  return (
    <ListPageLayout
      title="新建测试集"
      className="max-w-[1180px]"
      description="测试集是固定输入用例的业务分组。确认后进入用例编辑。"
      action={
        <Button
          variant="outline"
          className="w-full shrink-0 gap-2 border-hairline-strong text-muted-foreground hover:text-foreground sm:w-auto"
          onClick={() => router.push("/test/cases")}
        >
          <ChevronLeft size={16} />
          返回列表
        </Button>
      }
    >
      <ListPageSection>
        <label className="block">
          <div className="mb-2 text-sm font-medium text-foreground">
            测试集名称
          </div>
          <Input
            value={name}
            autoFocus
            onChange={(event) => setName(event.target.value)}
            placeholder="例如：事故基础流程"
            className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
          />
        </label>
      </ListPageSection>

      <ListPageSection>
        <div>
          <div className="mb-2 text-sm font-medium text-foreground">
            关联助手
          </div>
          {loadingAssistants ? (
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <Loader2 size={16} className="animate-spin" />
              正在加载助手…
            </div>
          ) : assistants.length > 0 ? (
            <Select value={assistantName} onValueChange={setAssistantName}>
              <SelectTrigger className="w-full border-hairline-strong bg-background">
                <SelectValue placeholder="选择关联助手" />
              </SelectTrigger>
              <SelectContent>
                {assistants.map((item) => (
                  <SelectItem key={item.id} value={item.name}>
                    {item.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <Input
              value={assistantName}
              onChange={(event) => setAssistantName(event.target.value)}
              placeholder="助手名称"
              className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
            />
          )}
        </div>
      </ListPageSection>

      <div className="flex items-center justify-end gap-3">
        <Button
          variant="outline"
          className="border-hairline-strong text-muted-foreground hover:text-foreground"
          disabled={creating}
          onClick={() => router.push("/test/cases")}
        >
          取消
        </Button>
        <Button
          className="gap-2"
          disabled={!name.trim() || creating}
          onClick={confirmCreate}
        >
          {creating ? (
            <Loader2 size={16} className="animate-spin" />
          ) : (
            <Rocket size={16} />
          )}
          创建测试集
        </Button>
      </div>
    </ListPageLayout>
  );
}

// ─── Suite 详情：左列表 + 右编辑 ─────────────────────────────────────────────

function caseToDraft(item: TestCase): CaseEditorDraft {
  return {
    name: item.name,
    inputMode: item.inputMode,
    contextTurns: item.contextTurns.map((turn) => ({ ...turn })),
    turns: cloneTurns(item.turns),
    overallCriteria: cloneOverallCriteria(item.overallCriteria),
  };
}

function draftsEqual(a: CaseEditorDraft, b: CaseEditorDraft) {
  return JSON.stringify(a) === JSON.stringify(b);
}

function createEmptyCaseDraft(): CaseEditorDraft {
  return {
    name: "未命名用例",
    inputMode: DEFAULT_INPUT_MODE,
    contextTurns: [],
    turns: [createEmptyFixedInputTurn()],
    overallCriteria: [],
  };
}

function applyInputMode(
  draft: CaseEditorDraft,
  mode: TestCaseInputMode,
): CaseEditorDraft {
  return { ...draft, inputMode: mode };
}

function SuiteDetailView({
  suiteId,
  initialCaseId,
}: {
  suiteId: string;
  initialCaseId?: string;
}) {
  const router = useRouter();
  const [initial] = useState(() => {
    const initialCases = listTestCases(suiteId);
    const initialCase =
      initialCases.find((item) => item.id === initialCaseId) ??
      initialCases[0] ??
      null;
    const initialDraft = initialCase ? caseToDraft(initialCase) : null;
    return {
      suite: getTestSuite(suiteId),
      cases: initialCases,
      selectedId: initialCase?.id ?? null,
      draft: initialDraft,
    };
  });
  const [suite, setSuite] = useState<TestSuite | null>(initial.suite);
  const [cases, setCases] = useState<TestCase[]>(initial.cases);
  const [selectedId, setSelectedId] = useState<string | null>(
    initial.selectedId,
  );
  const [search, setSearch] = useState("");
  const [draft, setDraft] = useState<CaseEditorDraft | null>(initial.draft);
  const [savedSnapshot, setSavedSnapshot] = useState<CaseEditorDraft | null>(
    initial.draft,
  );
  const [statusMessage, setStatusMessage] = useState("");
  const [selectionMode, setSelectionMode] = useState(false);
  const [checkedIds, setCheckedIds] = useState<Set<string>>(new Set());

  function reload(preferId?: string | null) {
    const nextSuite = getTestSuite(suiteId);
    const nextCases = listTestCases(suiteId);
    setSuite(nextSuite);
    setCases(nextCases);

    const nextSelected =
      (preferId && nextCases.some((item) => item.id === preferId)
        ? preferId
        : null) ??
      (selectedId && nextCases.some((item) => item.id === selectedId)
        ? selectedId
        : null) ??
      nextCases[0]?.id ??
      null;

    setSelectedId(nextSelected);
    if (nextSelected) {
      const item = nextCases.find((caseItem) => caseItem.id === nextSelected);
      if (item) {
        const nextDraft = caseToDraft(item);
        setDraft(nextDraft);
        setSavedSnapshot(nextDraft);
      }
    } else {
      setDraft(null);
      setSavedSnapshot(null);
    }
  }

  const filtered = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    return cases.filter((item) => {
      if (!keyword) return true;
      return [
        item.name,
        TEST_CASE_INPUT_MODE_SHORT_LABEL[item.inputMode],
      ]
        .join(" ")
        .toLowerCase()
        .includes(keyword);
    });
  }, [cases, search]);

  const dirty =
    draft !== null &&
    (selectedId === null ||
      savedSnapshot === null ||
      !draftsEqual(draft, savedSnapshot));

  const validationMessage = draft
    ? getTestCaseValidationMessage(draft)
    : "请先选择测试用例";
  const canSave =
    Boolean(draft?.name.trim()) && dirty && validationMessage === null;

  useEffect(() => {
    if (!dirty) return;

    function handleBeforeUnload(event: BeforeUnloadEvent) {
      event.preventDefault();
      event.returnValue = "";
    }

    function handleInternalLink(event: MouseEvent) {
      if (
        event.defaultPrevented ||
        event.button !== 0 ||
        event.metaKey ||
        event.ctrlKey ||
        event.shiftKey ||
        event.altKey
      ) {
        return;
      }
      const target = event.target;
      if (!(target instanceof Element)) return;
      const link = target.closest<HTMLAnchorElement>("a[href]");
      if (!link || link.target === "_blank" || link.hasAttribute("download")) {
        return;
      }
      const nextUrl = new URL(link.href, window.location.href);
      if (nextUrl.origin !== window.location.origin) return;
      if (
        nextUrl.pathname === window.location.pathname &&
        nextUrl.search === window.location.search
      ) {
        return;
      }
      if (window.confirm("当前用例有未保存修改，离开将丢弃。继续？")) {
        return;
      }
      event.preventDefault();
      event.stopImmediatePropagation();
    }

    window.addEventListener("beforeunload", handleBeforeUnload);
    document.addEventListener("click", handleInternalLink, true);
    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload);
      document.removeEventListener("click", handleInternalLink, true);
    };
  }, [dirty]);

  function selectCase(item: TestCase) {
    if (dirty && !window.confirm("当前用例有未保存修改，切换将丢弃。继续？")) {
      return;
    }
    setSelectedId(item.id);
    const nextDraft = caseToDraft(item);
    setDraft(nextDraft);
    setSavedSnapshot(nextDraft);
    setStatusMessage("");
  }

  function handleCreateCase() {
    if (dirty && !window.confirm("当前用例有未保存修改，新建将丢弃。继续？")) {
      return;
    }
    setSelectedId(null);
    setDraft(createEmptyCaseDraft());
    setSavedSnapshot(null);
    setStatusMessage("");
  }

  function handleSave() {
    if (!draft || validationMessage) return;
    const patch = {
      name: draft.name.trim() || "未命名用例",
      inputMode: draft.inputMode,
      contextTurns: draft.contextTurns,
      turns: draft.turns,
      overallCriteria: normalizeOverallCriteria(draft.overallCriteria),
    };

    let saved: TestCase | null;
    if (selectedId) {
      saved = updateTestCase(selectedId, patch);
    } else {
      const created = createTestCase({
        suiteId,
        name: patch.name,
      });
      saved = created ? updateTestCase(created.id, patch) : null;
    }
    if (!saved) return;
    const nextDraft = caseToDraft(saved);
    setSelectedId(saved.id);
    setCases(listTestCases(suiteId));
    setSuite(getTestSuite(suiteId));
    setDraft(nextDraft);
    setSavedSnapshot(nextDraft);
    setStatusMessage("已保存");
    window.setTimeout(() => setStatusMessage(""), 2000);
  }

  function handleCancelNewCase() {
    reload();
    setStatusMessage("");
  }

  function handleBackToList() {
    if (dirty && !window.confirm("当前用例有未保存修改，离开将丢弃。继续？")) {
      return;
    }
    router.push("/test/cases");
  }

  function handleDuplicateCase(item: TestCase) {
    if (dirty && !window.confirm("当前用例有未保存修改，复制将丢弃。继续？")) {
      return;
    }
    const copied = duplicateTestCase(item.id);
    if (!copied) return;
    reload(copied.id);
    setStatusMessage("");
  }

  function handleDeleteCase(item: TestCase) {
    if (!window.confirm(`确定删除测试用例“${item.name}”吗？`)) return;
    removeTestCase(item.id);
    setCheckedIds((prev) => {
      const next = new Set(prev);
      next.delete(item.id);
      return next;
    });
    reload(selectedId === item.id ? null : selectedId);
  }

  function handleDeleteSelected() {
    if (!selectedId || !draft) return;
    if (
      !window.confirm(
        `确定删除测试用例“${draft.name.trim() || "未命名用例"}”吗？`,
      )
    ) {
      return;
    }
    removeTestCase(selectedId);
    reload(null);
  }

  function handleEnterSelectionMode() {
    setSelectionMode(true);
    setCheckedIds(new Set());
  }

  function handleExitSelectionMode() {
    setSelectionMode(false);
    setCheckedIds(new Set());
  }

  function handleToggleChecked(id: string) {
    setCheckedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  function handleToggleSelectAll() {
    const allChecked =
      filtered.length > 0 && filtered.every((item) => checkedIds.has(item.id));
    if (allChecked) {
      setCheckedIds((prev) => {
        const next = new Set(prev);
        for (const item of filtered) next.delete(item.id);
        return next;
      });
      return;
    }
    setCheckedIds((prev) => {
      const next = new Set(prev);
      for (const item of filtered) next.add(item.id);
      return next;
    });
  }

  function handleBulkDelete() {
    const ids = filtered
      .filter((item) => checkedIds.has(item.id))
      .map((item) => item.id);
    if (ids.length === 0) return;
    if (!window.confirm(`确定删除选中的 ${ids.length} 个测试用例吗？`)) return;
    removeTestCases(ids);
    handleExitSelectionMode();
    reload(selectedId && ids.includes(selectedId) ? null : selectedId);
  }

  function handleReorder(orderedIds: string[]) {
    reorderTestCases(suiteId, orderedIds);
    setCases(listTestCases(suiteId));
  }

  function renameSuite(nextName: string) {
    if (!suite || nextName === suite.name) return;
    const saved = updateTestSuite(suite.id, { name: nextName });
    if (saved) setSuite(saved);
  }

  if (!suite) {
    return (
      <div className="mx-auto flex w-full max-w-[1280px] flex-col gap-4 py-16">
        <div className="font-medium text-destructive">测试集不存在</div>
        <Button
          variant="outline"
          size="sm"
          className="w-fit border-hairline-strong text-muted-foreground hover:text-foreground"
          onClick={() => router.push("/test/cases")}
        >
          返回列表
        </Button>
      </div>
    );
  }

  return (
    <>
      <TopbarPortal>
        <div className="flex h-full min-w-0 flex-1 items-center gap-2 sm:-ml-2 lg:-ml-4">
          <EditorBackButton
            ariaLabel="返回测试集列表"
            onClick={handleBackToList}
          />
          <EditableTitle
            value={suite.name}
            onChange={renameSuite}
            placeholder="未命名测试集"
            editLabel="测试集名称"
          />
          <AssistantIdentity assistantId={suite.id} entityLabel="测试集" />
        </div>
      </TopbarPortal>

      <div
        data-app-content="full-bleed"
        className="flex h-full min-h-0 flex-col overflow-hidden bg-background lg:flex-row"
      >
        <SuiteCaseList
          cases={cases}
          filtered={filtered}
          selectedId={selectedId}
          search={search}
          selectionMode={selectionMode}
          checkedIds={checkedIds}
          onSearchChange={setSearch}
          onSelectCase={selectCase}
          onCreateCase={handleCreateCase}
          onDuplicateCase={handleDuplicateCase}
          onDeleteCase={handleDeleteCase}
          onEnterSelectionMode={handleEnterSelectionMode}
          onExitSelectionMode={handleExitSelectionMode}
          onToggleChecked={handleToggleChecked}
          onToggleSelectAll={handleToggleSelectAll}
          onBulkDelete={handleBulkDelete}
          onReorder={handleReorder}
        />

        <main className="flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden bg-background">
          {!draft ? (
            <div className="flex flex-1 items-center justify-center px-6 text-sm text-muted-foreground">
              请选择左侧用例，或新建一个测试用例。
            </div>
          ) : (
            <>
              <div className="flex shrink-0 flex-wrap items-center gap-2 border-b border-hairline px-4 py-3 sm:gap-3 sm:px-6">
                <EditableTitle
                  value={draft.name}
                  onChange={(value) =>
                    setDraft({ ...draft, name: value || "未命名用例" })
                  }
                  placeholder="未命名用例"
                  editLabel="用例名称"
                  variant="panel"
                  allowEmpty
                />

                <InputModePicker
                  value={draft.inputMode}
                  onChange={(mode) => setDraft(applyInputMode(draft, mode))}
                />

                <div className="ml-auto flex shrink-0 items-center gap-2">
                  {dirty && validationMessage ? (
                    <span
                      className="max-w-56 truncate text-xs text-destructive"
                      title={validationMessage}
                      role="status"
                    >
                      {validationMessage}
                    </span>
                  ) : dirty ? (
                    <span className="text-xs text-amber-600">未保存</span>
                  ) : statusMessage ? (
                    <span className="text-xs text-muted-foreground">
                      {statusMessage}
                    </span>
                  ) : null}
                  <Button
                    size="sm"
                    className="gap-1.5"
                    disabled={!canSave}
                    title={validationMessage ?? undefined}
                    onClick={handleSave}
                  >
                    <Save size={14} />
                    保存
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    className={
                      selectedId
                        ? "border-hairline-strong text-muted-foreground hover:text-destructive"
                        : "border-hairline-strong text-muted-foreground hover:text-foreground"
                    }
                    onClick={
                      selectedId ? handleDeleteSelected : handleCancelNewCase
                    }
                  >
                    {selectedId ? <Trash2 size={14} /> : <X size={14} />}
                    {selectedId ? "删除" : "取消"}
                  </Button>
                </div>
              </div>

              {draft.inputMode === "fixed_script_text" ? (
                <NextReplyEditorBody draft={draft} onChange={setDraft} />
              ) : (
                <div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-2 px-6 text-center">
                  <div className="text-sm font-medium text-foreground">
                    {TEST_CASE_INPUT_MODE_LABEL[draft.inputMode]} · 开发中
                  </div>
                  <p className="max-w-sm text-xs leading-5 text-muted-foreground">
                    当前仅支持「固定脚本 · 文字」编辑器，其它输入模式稍后接入。
                  </p>
                </div>
              )}
            </>
          )}
        </main>
      </div>
    </>
  );
}
