"use client";

import { useMemo, useState } from "react";
import dynamic from "next/dynamic";
import { Clock3, Globe2, Share2, Sparkles, UserRound } from "lucide-react";

import { AppShell } from "@/components/AppShell";
import { CharacterGenerator } from "@/components/generation/CharacterGenerator";
import { WorldGenerator } from "@/components/generation/WorldGenerator";
import { Badge } from "@/components/ui/Badge";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { EmptyState } from "@/components/ui/EmptyState";
import { PageHeader } from "@/components/ui/PageHeader";
import { SegmentedControl } from "@/components/ui/SegmentedControl";
import type {
  CharacterCardView,
  ProjectResponse,
  WorldEntityCardView,
} from "@/lib/api/types";
import {
  mergeCharacterCards,
  worldEntityRules,
} from "@/lib/generation/cards";

type CodexTab = "characters" | "world" | "timeline";

interface CodexPageProps {
  project: ProjectResponse;
  // 后端读端点（GET .../characters / .../world_entities）拉来的跨会话全量真源。
  initialCharacters: CharacterCardView[];
  initialWorldEntities: WorldEntityCardView[];
  // 进页可经 ?gen=character|world 直接打开对应生成器（命令面板动作跳转）。
  initialTab?: CodexTab;
}

const TABS: { key: CodexTab; label: string }[] = [
  { key: "characters", label: "人物" },
  { key: "world", label: "世界观" },
  { key: "timeline", label: "时间线" },
];

// 关系图谱（React Flow）只在客户端渲染：ssr:false 绕开 canvas/window 依赖，
// 并把 React Flow 及其样式拆到独立 chunk，进人物 tab 才加载。
const RelationshipGraph = dynamic(
  () =>
    import("@/components/characters/RelationshipGraph").then(
      (mod) => mod.RelationshipGraph,
    ),
  {
    ssr: false,
    loading: () => (
      <div className="flex h-[28rem] items-center justify-center rounded border border-line bg-bg text-sm text-ink-soft">
        关系图谱加载中…
      </div>
    ),
  },
);

// 设定库 Codex（UX §6.5）：管理人物 / 世界观 / 时间线。
// 初始列表来自后端读端点（跨会话全量真源）；本会话新入库的角色卡再合并补显，
// 故刷新后不再为空、且不与真源重复（按 name 去重，见 mergeCharacterCards）。
// 世界观本期无入库端点（仅生成预览）→ 展示真源 + 生成器预览。时间线为 P2/派生，暂占位。
export function CodexPage({
  project,
  initialCharacters,
  initialWorldEntities,
  initialTab = "characters",
}: CodexPageProps) {
  const [tab, setTab] = useState<CodexTab>(initialTab);
  // 本会话内新入库的角色（即时回显，无需刷新即见）。
  const [sessionCards, setSessionCards] = useState<CharacterCardView[]>([]);

  // 真源（初始全量）+ 本会话新卡，按 name 去重合并。
  const characters = useMemo(
    () => mergeCharacterCards(initialCharacters, sessionCards),
    [initialCharacters, sessionCards],
  );

  return (
    <AppShell
      title={`〈${project.title}〉`}
      subtitle="设定库"
      projectId={project.id}
      activeNav="codex"
    >
      <div className="flex h-[calc(100vh-var(--chrome,4rem))] flex-col p-4">
        <PageHeader
          title="设定库"
          description="人物、世界观与时间线共同构成写作时的真相源。AI 生成内容也要先预览、再确认入库。"
        />
        <SegmentedControl
          className="mb-4 w-fit"
          ariaLabel="设定库分区"
          value={tab}
          onChange={setTab}
          options={TABS.map((t) => ({ value: t.key, label: t.label }))}
        />

        <div className="min-h-0 flex-1 overflow-auto">
          {tab === "characters" ? (
            <div className="flex flex-col gap-4">
              <Card as="section" className="p-4">
                <h3 className="mb-3 font-serif text-sm text-ink">
                  已入库人物（{characters.length}）
                </h3>
                {characters.length > 0 ? (
                  <ul className="grid grid-cols-1 gap-3 lg:grid-cols-2">
                    {characters.map((c, i) => (
                      <li
                        key={`${c.name}-${i}`}
                        className="rounded border border-line bg-bg p-3 text-sm"
                      >
                        <div className="mb-2 flex items-center gap-2">
                          <span className="flex h-8 w-8 items-center justify-center rounded bg-[var(--color-cinnabar-wash)] text-cinnabar">
                            <UserRound className="h-4 w-4" aria-hidden="true" />
                          </span>
                          <div className="min-w-0">
                            <p className="truncate font-serif text-base text-ink">
                              {c.name}
                            </p>
                            <p className="text-xs text-ink-soft">{c.role}</p>
                          </div>
                        </div>
                        {c.relations && c.relations.length > 0 ? (
                          <ul className="mt-1 flex flex-wrap gap-1">
                            {c.relations.map((r, j) => (
                              <li
                                key={`${r.name}-${r.kind}-${j}`}
                                className="rounded bg-panel px-1.5 py-0.5 text-2xs"
                                title={r.note ?? undefined}
                              >
                                {r.kind} · {r.name}
                              </li>
                            ))}
                          </ul>
                        ) : null}
                      </li>
                    ))}
                  </ul>
                ) : (
                  <EmptyState
                    icon={UserRound}
                    title="暂无入库人物"
                    description="先生成或手动整理主角、配角与关系，再让写作上下文稳定引用。"
                    action={
                      <Button
                        onClick={() =>
                          document
                            .getElementById("character-generator")
                            ?.scrollIntoView({ block: "center" })
                        }
                        variant="primary"
                        size="sm"
                      >
                        <Sparkles className="h-4 w-4" aria-hidden="true" />
                        生成角色
                      </Button>
                    }
                    className="bg-bg/50"
                  />
                )}
              </Card>
              {characters.length > 0 ? (
                <Card as="section" className="p-4">
                  <h3 className="mb-3 flex items-center gap-2 font-serif text-sm text-ink">
                    <Share2 className="h-4 w-4 text-cinnabar" aria-hidden="true" />
                    关系图谱
                  </h3>
                  <RelationshipGraph characters={characters} />
                </Card>
              ) : null}
              <div id="character-generator">
                <CharacterGenerator
                  projectId={project.id}
                  onIngested={(_, cards) =>
                    setSessionCards((prev) => [...prev, ...cards])
                  }
                />
              </div>
            </div>
          ) : null}

          {tab === "world" ? (
            <div className="flex flex-col gap-4">
              <Card as="section" className="p-4">
                <h3 className="mb-3 font-serif text-sm text-ink">
                  已入库世界观（{initialWorldEntities.length}）
                </h3>
                {initialWorldEntities.length > 0 ? (
                  <div className="grid grid-cols-1 gap-3 lg:grid-cols-2">
                    {initialWorldEntities.map((entity, i) => (
                      <article
                        key={`${entity.name}-${i}`}
                        className="rounded border border-line bg-bg p-3 text-sm"
                      >
                        <header className="mb-2 flex items-center gap-2">
                          <Globe2
                            className="h-4 w-4 text-cinnabar"
                            aria-hidden="true"
                          />
                          <span className="font-serif text-base text-ink">
                            {entity.name}
                          </span>
                          <Badge>
                            {entity.type}
                          </Badge>
                        </header>
                        {worldEntityRules(entity).length > 0 ? (
                          <ul className="flex list-disc flex-col gap-1 pl-5 text-ink-soft">
                            {worldEntityRules(entity).map((rule, j) => (
                              <li key={j}>{rule}</li>
                            ))}
                          </ul>
                        ) : (
                          <p className="text-ink-soft">（无显式硬规则）</p>
                        )}
                      </article>
                    ))}
                  </div>
                ) : (
                  <EmptyState
                    icon={Globe2}
                    title="暂无入库世界观"
                    description="先沉淀硬规则、地理、势力与能力边界，减少后续章节设定漂移。"
                    action={
                      <Button
                        onClick={() =>
                          document
                            .getElementById("world-generator")
                            ?.scrollIntoView({ block: "center" })
                        }
                        variant="primary"
                        size="sm"
                      >
                        <Sparkles className="h-4 w-4" aria-hidden="true" />
                        生成世界观
                      </Button>
                    }
                    className="bg-bg/50"
                  />
                )}
              </Card>
              <div id="world-generator">
                <WorldGenerator projectId={project.id} />
              </div>
            </div>
          ) : null}

          {tab === "timeline" ? (
            <EmptyState
              icon={Clock3}
              title="时间线尚未启用"
              description="时间线会从章节摘要、伏笔窗口和验收记录派生，后续可用于全书一致性扫描。"
            />
          ) : null}
        </div>
      </div>
    </AppShell>
  );
}
