"use client";

import { Minus, Pin, PinOff, Plus, RotateCcw, Undo2, X } from "lucide-react";

import { ThinkingIndicator } from "@/components/ThinkingIndicator";
import { Button } from "@/components/ui/Button";
import { SectionHeader } from "@/components/ui/SectionHeader";
import { StatusNote } from "@/components/ui/StatusNote";
import { buttonClass } from "@/lib/ui/variants";
import {
  isPinned,
  kindLabel,
  reasonLabel,
  RECENT_N_MAX,
  RECENT_N_MIN,
  type InjectionEntity,
  type InjectionEntityRef,
} from "@/lib/workbench/injection";
import { useInjection } from "@/lib/workbench/useInjection";

interface ChapterAssistantProps {
  projectId: string;
  chapterNo: number;
}

// 右栏「本章助手」（UX §6.3）。
// 「本章注入（透明）」读 B0 端点，列出确定性选中的设定/角色 + 入选理由徽标，
// 并让作者 📌置顶 / ✕排除 / 调近 N 章（可控版）——「看到的=写章用的」信任牌（不变量 #6）。
// 桌面 aside 包裹；移动端经 Workbench 抽屉复用 AssistantContent。
export function ChapterAssistant({ projectId, chapterNo }: ChapterAssistantProps) {
  return (
    <aside className="hidden border-l border-line bg-panel py-4 xl:block">
      <AssistantContent projectId={projectId} chapterNo={chapterNo} />
    </aside>
  );
}

export function AssistantContent({ projectId, chapterNo }: ChapterAssistantProps) {
  const injection = useInjection(projectId, chapterNo);
  const data = injection.data;
  const selected = data?.selected ?? [];
  const excluded = data?.excluded ?? [];

  return (
    <div className="px-4">
      <SectionHeader
        title="本章参考"
        action={
          injection.saving ? (
            <ThinkingIndicator
              label="保存中"
              className="text-xs text-ink-soft"
            />
          ) : null
        }
      />

      <section className="mt-4">
        <SectionHeader
          title="AI 写这章会参考"
          action={
            data ? (
              <RecentStepper
                value={data.recent_n}
                disabled={injection.saving}
                onChange={injection.setRecentN}
              />
            ) : null
          }
        />

        {injection.loading ? (
          <p className="mt-2 text-xs text-ink-soft">加载参考信息…</p>
        ) : !data ? (
          // 首次加载失败：data 仍为空 → 满屏错误框 + 重试。
          <StatusNote variant="danger" className="mt-2 text-xs" title="参考信息暂不可用">
            <p>请检查后端连接后重试。</p>
            <button
              type="button"
              onClick={injection.reload}
              className={buttonClass({ variant: "outline", size: "sm", className: "mt-2" })}
            >
              <RotateCcw className="h-3.5 w-3.5" aria-hidden="true" />
              重试
            </button>
          </StatusNote>
        ) : (
          <>
            {injection.saveError ? (
              // 保存失败：悬浮提示，不替换列表；可关闭 + 重试上一次覆盖。
              <StatusNote variant="danger" className="mt-2 text-xs" title={injection.saveError}>
                <div className="mt-1 flex items-center gap-2">
                  <button
                    type="button"
                    onClick={() => void injection.retrySave()}
                    disabled={injection.saving}
                    className={buttonClass({ variant: "outline", size: "sm" })}
                  >
                    <RotateCcw className="h-3.5 w-3.5" aria-hidden="true" />
                    重试
                  </button>
                  <button
                    type="button"
                    onClick={injection.clearSaveError}
                    aria-label="关闭保存失败提示"
                    className={buttonClass({ variant: "ghost", size: "sm" })}
                  >
                    <X className="h-3.5 w-3.5" aria-hidden="true" />
                    关闭
                  </button>
                </div>
              </StatusNote>
            ) : null}

            {selected.length === 0 ? (
              <p className="mt-2 rounded border border-dashed border-line bg-bg p-3 text-xs text-ink-soft">
                这一章 AI 还没有要参考的设定/角色。可在大纲里点名，或从下方「已排除」里恢复。
              </p>
            ) : (
              <ul className="mt-2 space-y-2">
                {selected.map((entity) => (
                  <EntityRow
                    key={`${entity.kind}:${entity.name}`}
                    entity={entity}
                    pinned={isPinned(
                      { pinned: data.pinned, excluded: data.excluded, recent_n: data.recent_n },
                      entity,
                    )}
                    disabled={injection.saving}
                    onTogglePin={injection.togglePin}
                    onExclude={injection.exclude}
                  />
                ))}
              </ul>
            )}
          </>
        )}

        {excluded.length > 0 ? (
          <div className="mt-3">
            <SectionHeader title="已排除（本章不参考）" />
            <ul className="mt-1 space-y-1">
              {excluded.map((ref) => (
                <ExcludedRow
                  key={`${ref.kind}:${ref.name}`}
                  refItem={ref}
                  disabled={injection.saving}
                  onRestore={injection.restore}
                />
              ))}
            </ul>
          </div>
        ) : null}
      </section>

      <section className="mt-6">
        <SectionHeader
          title="写完后检查"
          description="写完这章，AI 会把一致性、伏笔、文风、节奏各查一遍。到左栏或底栏的「审稿」逐条过。"
        />
      </section>
    </div>
  );
}

interface EntityRowProps {
  entity: InjectionEntity;
  pinned: boolean;
  disabled: boolean;
  onTogglePin: (ref: InjectionEntityRef) => void;
  onExclude: (ref: InjectionEntityRef) => void;
}

function EntityRow({ entity, pinned, disabled, onTogglePin, onExclude }: EntityRowProps) {
  const ref: InjectionEntityRef = { kind: entity.kind, name: entity.name };
  return (
    <li className="rounded border border-line bg-bg p-2">
      <div className="flex items-center gap-2">
        <span className="rounded bg-panel px-1.5 py-0.5 text-2xs text-ink-soft">
          {kindLabel(entity.kind)}
        </span>
        <span className="text-sm text-ink">{entity.name}</span>
        <div className="ml-auto flex items-center gap-1">
          <Button
            variant="ghost"
            size="icon"
            disabled={disabled}
            aria-pressed={pinned}
            aria-label={
              pinned ? `取消置顶 ${entity.name}` : `置顶 ${entity.name}（一定参考）`
            }
            onClick={() => onTogglePin(ref)}
            className={pinned ? "text-cinnabar" : undefined}
          >
            {pinned ? (
              <Pin className="h-4 w-4" aria-hidden="true" />
            ) : (
              <PinOff className="h-4 w-4" aria-hidden="true" />
            )}
          </Button>
          <Button
            variant="ghost"
            size="icon"
            disabled={disabled}
            aria-label={`排除 ${entity.name}（本章不参考）`}
            onClick={() => onExclude(ref)}
          >
            <X className="h-4 w-4" aria-hidden="true" />
          </Button>
        </div>
      </div>
      <div className="mt-1.5 flex flex-wrap gap-1">
        {(entity.reasons ?? []).map((reason) => (
          <span
            key={reason}
            className="rounded bg-[var(--color-cinnabar-wash)] px-1.5 py-0.5 text-2xs text-cinnabar"
          >
            {reasonLabel(reason)}
          </span>
        ))}
      </div>
    </li>
  );
}

interface ExcludedRowProps {
  refItem: InjectionEntityRef;
  disabled: boolean;
  onRestore: (ref: InjectionEntityRef) => void;
}

function ExcludedRow({ refItem, disabled, onRestore }: ExcludedRowProps) {
  return (
    <li className="flex items-center gap-2 rounded border border-dashed border-line px-2 py-1">
      <span className="text-2xs text-ink-soft">{kindLabel(refItem.kind)}</span>
      <span className="text-xs text-ink-soft line-through">{refItem.name}</span>
      <Button
        variant="ghost"
        size="icon"
        disabled={disabled}
        aria-label={`恢复 ${refItem.name}（回到自动判定）`}
        onClick={() => onRestore(refItem)}
        className="ml-auto text-cinnabar"
      >
        <Undo2 className="h-4 w-4" aria-hidden="true" />
      </Button>
    </li>
  );
}

interface RecentStepperProps {
  value: number;
  disabled: boolean;
  onChange: (n: number) => void;
}

// 「关联近 N 章」步进器：覆盖近况摘要回看章数（钳在 [MIN, MAX]）。
function RecentStepper({ value, disabled, onChange }: RecentStepperProps) {
  return (
    <div className="flex items-center gap-1 text-2xs text-ink-soft">
      <span>近</span>
      <Button
        variant="ghost"
        size="icon"
        disabled={disabled || value <= RECENT_N_MIN}
        aria-label="减少关联章数"
        onClick={() => onChange(value - 1)}
      >
        <Minus className="h-4 w-4" aria-hidden="true" />
      </Button>
      <span className="w-4 text-center tabular-nums text-ink">{value}</span>
      <Button
        variant="ghost"
        size="icon"
        disabled={disabled || value >= RECENT_N_MAX}
        aria-label="增加关联章数"
        onClick={() => onChange(value + 1)}
      >
        <Plus className="h-4 w-4" aria-hidden="true" />
      </Button>
      <span>章</span>
    </div>
  );
}
