"use client";

import { useMemo, useState } from "react";
import { ListTree, Sparkles } from "lucide-react";

import { AppShell } from "@/components/AppShell";
import { Button } from "@/components/ui/Button";
import { EmptyState } from "@/components/ui/EmptyState";
import { PageHeader } from "@/components/ui/PageHeader";
import { Select } from "@/components/ui/Select";
import { StatusNote } from "@/components/ui/StatusNote";
import { TextInput } from "@/components/ui/TextInput";
import type { OutlineChapterView, ProjectResponse } from "@/lib/api/types";
import {
  distinctVolumes,
  filterByViewVolume,
  groupByVolume,
  type ViewVolume,
} from "@/lib/outline/outline";
import { useOutline } from "@/lib/outline/useOutline";
import { OutlineChapterRow } from "./OutlineChapterRow";

interface OutlineEditorProps {
  project: ProjectResponse;
  initialChapters: OutlineChapterView[];
}

// 大纲编辑器主体（UX §6.7）。RSC 种入已存大纲；Client 承载生成（POST .../outline）。
// 无凭据 → 503 LLM_UNAVAILABLE 经 error 检出、引导去设置。
export function OutlineEditor({
  project,
  initialChapters,
}: OutlineEditorProps) {
  const { chapters, status, error, generate } = useOutline(initialChapters);
  // 生成目标卷与「正在看的卷」共用一个心智：选具体卷即把生成目标设为该卷。
  const [volume, setVolume] = useState(1);
  const [viewVolume, setViewVolume] = useState<ViewVolume>("all");
  // 「重新排大纲」破坏性覆盖的两段式确认（仅目标卷已有章节时出现）。
  const [confirming, setConfirming] = useState(false);
  const availableVolumes = useMemo(() => distinctVolumes(chapters), [chapters]);
  const volumes = useMemo(
    () => groupByVolume(filterByViewVolume(chapters, viewVolume)),
    [chapters, viewVolume],
  );
  const generating = status === "generating";
  // 目标卷已有章节 → 生成是破坏性替换，文案/确认都要变。
  const targetHasChapters = useMemo(
    () => filterByViewVolume(chapters, volume).length > 0,
    [chapters, volume],
  );

  // 选具体卷时把生成目标对齐到所看卷，消除「看卷 A、却生成卷 B」的易混。
  const onViewVolumeChange = (next: ViewVolume): void => {
    setViewVolume(next);
    setConfirming(false);
    if (next !== "all") setVolume(next);
  };

  const onVolumeChange = (next: number): void => {
    setVolume(Math.max(1, next || 1));
    setConfirming(false);
  };

  const runGenerate = (): void => {
    setConfirming(false);
    void generate(project.id, volume);
  };

  // 安全卷直接生成；破坏性卷先进入两段式确认。
  const onGenerateClick = (): void => {
    if (targetHasChapters) {
      setConfirming(true);
      return;
    }
    runGenerate();
  };

  const generateLabel = generating
    ? "排大纲中…"
    : `${targetHasChapters ? "重新排大纲" : "AI 排大纲"} · 卷 ${volume}`;

  return (
    <AppShell
      title={`〈${project.title}〉`}
      subtitle="大纲"
      projectId={project.id}
      activeNav="outline"
    >
      <div className="flex h-[calc(100vh-var(--chrome,4rem))] flex-col p-6">
        <PageHeader
          title="大纲"
          description="按卷组织章节节拍，写作台会把当前章节拍注入生成上下文。"
        />

        {/* 卷/视图/生成控件独立成全宽工具栏行（窄屏自动换行，不用脆弱的 ml-auto）。 */}
        <div className="mb-4 flex flex-wrap items-center gap-2">
          {availableVolumes.length > 0 ? (
            <label
              htmlFor="view-vol"
              className="flex items-center gap-1 text-xs text-ink-soft"
            >
              查看
              <Select
                id="view-vol"
                value={viewVolume === "all" ? "all" : String(viewVolume)}
                onChange={(e) =>
                  onViewVolumeChange(
                    e.target.value === "all" ? "all" : Number(e.target.value),
                  )
                }
                controlSize="sm"
              >
                <option value="all">全部</option>
                {availableVolumes.map((v) => (
                  <option key={v} value={String(v)}>
                    卷 {v}
                  </option>
                ))}
              </Select>
            </label>
          ) : null}

          {availableVolumes.length > 0 ? (
            <span className="ml-1 h-4 w-px bg-line" aria-hidden="true" />
          ) : null}

          <label
            htmlFor="vol"
            className="flex items-center gap-1 text-xs text-ink-soft"
          >
            生成到 卷
            <TextInput
              id="vol"
              inputMode="numeric"
              value={volume}
              onChange={(e) => onVolumeChange(Number(e.target.value))}
              controlSize="sm"
              className="w-16"
            />
          </label>

          <Button
            disabled={generating}
            onClick={onGenerateClick}
            variant="primary"
          >
            <Sparkles className="h-4 w-4" aria-hidden="true" />
            {generateLabel}
          </Button>
        </div>

        {confirming ? (
          <StatusNote
            variant="warning"
            title={`卷 ${volume} 已有章节`}
            className="mb-4"
          >
            <p>重新排大纲会替换卷 {volume} 的全部条目（其它卷不受影响）。</p>
            <div className="mt-2 flex flex-wrap gap-2">
              <Button onClick={runGenerate} variant="danger" size="sm">
                确认替换卷 {volume}
              </Button>
              <Button
                onClick={() => setConfirming(false)}
                variant="secondary"
                size="sm"
              >
                取消
              </Button>
            </div>
          </StatusNote>
        ) : null}

        {error ? (
          <StatusNote variant="danger" title="大纲生成失败" className="mb-4">
            {error.text}
            {error.actionHref ? (
              <>
                {" "}
                <a
                  href={error.actionHref}
                  className="underline hover:text-cinnabar"
                >
                  {error.actionLabel}
                </a>
              </>
            ) : null}
          </StatusNote>
        ) : null}

        <div className="min-h-0 flex-1 overflow-auto">
          {volumes.length === 0 ? (
            <EmptyState
              icon={ListTree}
              title={
                chapters.length > 0 && viewVolume !== "all"
                  ? `卷 ${viewVolume} 暂无大纲`
                  : "暂无大纲"
              }
              description={
                chapters.length > 0 && viewVolume !== "all"
                  ? "切到「全部」查看其它卷，或为当前卷生成章节节拍。"
                  : "点击「AI 排大纲」生成逐章节拍与伏笔窗口，再回到写作台逐章推进。"
              }
              action={
                <Button
                  disabled={generating}
                  onClick={onGenerateClick}
                  variant="primary"
                  size="sm"
                >
                  <Sparkles className="h-4 w-4" aria-hidden="true" />
                  {generateLabel}
                </Button>
              }
            />
          ) : (
            volumes.map((group) => (
              <section key={group.volume} className="mb-6">
                <h2 className="mb-2 font-serif text-base text-ink">
                  卷 {group.volume}
                </h2>
                <ul className="space-y-1">
                  {group.chapters.map((ch) => (
                    <OutlineChapterRow
                      key={ch.no}
                      chapter={ch}
                      projectId={project.id}
                    />
                  ))}
                </ul>
              </section>
            ))
          )}
        </div>
      </div>
    </AppShell>
  );
}
