"use client";

import { useCallback, useEffect, useState } from "react";

import { ConflictCard } from "@/components/review/ConflictCard";
import { useToast } from "@/components/Toast";
import { Button } from "@/components/ui/Button";
import { StatusNote } from "@/components/ui/StatusNote";
import { api } from "@/lib/api/client";
import { buildResumeRequest } from "@/lib/chain/chain";
import { friendlyFromApiError } from "@/lib/errors/messages";
import type { ReviewConflict } from "@/lib/review/sse";
import {
  allResolved,
  emptyDecisions,
  setNote,
  setVerdict,
  unresolvedIndices,
  type DecisionDraft,
  type Verdict,
} from "@/lib/review/decisions";
import { latestReview, normalizeConflicts } from "@/lib/review/history";

interface ChainAdjudicationProps {
  projectId: string;
  jobId: string;
  // interrupt 命中的章号（读其最近审稿冲突供裁决）。
  chapterNo: number;
  // 续跑发起后回调（父层重启轮询）。
  onResumed: () => void;
}

type LoadState = "loading" | "ready" | "error";

// 链裁决面板（净新但复用满）：读 awaiting 章最近审稿 → 渲 ConflictCard（每冲突一张，复用审稿页
// 组件 + decisions.ts 纯逻辑）→ 全决后 POST resume（buildResumeRequest 复用 accept 裁决组装）。
// 链无在手草稿正文 → 无段内定位（snippet=null/locatable=false），裁决纯靠 suggestion + 补丁对。
export function ChainAdjudication({
  projectId,
  jobId,
  chapterNo,
  onResumed,
}: ChainAdjudicationProps) {
  const toast = useToast();
  const [loadState, setLoadState] = useState<LoadState>("loading");
  const [conflicts, setConflicts] = useState<ReviewConflict[]>([]);
  const [drafts, setDrafts] = useState<DecisionDraft[]>([]);
  const [resuming, setResuming] = useState(false);

  // 拉取 awaiting 章最近审稿冲突。抽成可复用回调，供进场 effect 与「重新加载」按钮共用。
  const load = useCallback(async (): Promise<boolean> => {
    setLoadState("loading");
    try {
      const { data, error } = await api.GET(
        "/projects/{project_id}/chapters/{chapter_no}/reviews",
        {
          params: {
            path: { project_id: projectId, chapter_no: chapterNo },
          },
        },
      );
      if (error || !data) {
        setLoadState("error");
        return false;
      }
      const next = normalizeConflicts(latestReview(data.reviews));
      setConflicts(next);
      setDrafts(emptyDecisions(next.length));
      setLoadState("ready");
      return true;
    } catch {
      setLoadState("error");
      return false;
    }
  }, [projectId, chapterNo]);

  useEffect(() => {
    let active = true;
    void (async () => {
      // 进场加载：组件已卸载则丢弃结果（避免 setState-after-unmount）。
      if (!active) return;
      await load();
    })();
    return () => {
      active = false;
    };
  }, [load]);

  const onVerdict = useCallback((index: number, verdict: Verdict): void => {
    setDrafts((prev) => setVerdict(prev, index, verdict));
  }, []);

  const onNote = useCallback((index: number, note: string): void => {
    setDrafts((prev) => setNote(prev, index, note));
  }, []);

  const onResume = useCallback(async (): Promise<void> => {
    if (!allResolved(drafts)) {
      toast("仍有未裁决的冲突，请先逐条裁决。", "error");
      return;
    }
    setResuming(true);
    try {
      const { error } = await api.POST(
        "/projects/{project_id}/chains/runs/{job_id}/resume",
        {
          params: { path: { project_id: projectId, job_id: jobId } },
          body: buildResumeRequest(drafts),
        },
      );
      if (error) {
        toast(friendlyFromApiError(error).text, "error");
        setResuming(false);
        return;
      }
      onResumed();
    } catch {
      toast("续跑请求异常，请检查网络。", "error");
      setResuming(false);
    }
  }, [drafts, projectId, jobId, onResumed, toast]);

  if (loadState === "loading") {
    return <p className="text-sm text-ink-soft">加载第 {chapterNo} 章冲突…</p>;
  }
  if (loadState === "error") {
    return (
      <StatusNote variant="danger" title={`加载第 ${chapterNo} 章审稿冲突失败`}>
        <p>请检查网络后重新加载。</p>
        <Button
          variant="outline"
          size="sm"
          onClick={() => void load()}
          className="mt-3"
        >
          重新加载
        </Button>
      </StatusNote>
    );
  }

  const pending = unresolvedIndices(drafts);

  return (
    <section
      className="flex flex-col gap-3 rounded border border-line bg-panel p-5"
      aria-label={`第 ${chapterNo} 章冲突裁决`}
    >
      <h2 className="font-serif text-lg text-ink">
        第 {chapterNo} 章冲突裁决（{conflicts.length}）
      </h2>
      {conflicts.length === 0 ? (
        <p className="text-sm text-ink-soft">
          该章无未决冲突，可直接续跑。
        </p>
      ) : (
        <ul className="flex flex-col gap-3">
          {conflicts.map((conflict, i) => {
            const draft = drafts[i] ?? { verdict: null, note: "" };
            return (
              <ConflictCard
                key={i}
                index={i}
                total={conflicts.length}
                conflict={conflict}
                draft={draft}
                missing={false}
                snippet={null}
                locatable={false}
                rewriting={false}
                onVerdict={onVerdict}
                onNote={onNote}
                onJump={() => {}}
              />
            );
          })}
        </ul>
      )}

      <Button
        variant="primary"
        onClick={() => void onResume()}
        disabled={resuming || !allResolved(drafts)}
        className="self-start"
      >
        {resuming ? "续跑中…" : "裁决完成，续跑"}
      </Button>
      {pending.length > 0 ? (
        <p className="text-xs text-conflict">
          还有 {pending.length} 条冲突未裁决。
        </p>
      ) : null}
    </section>
  );
}
