"use client";

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

import { api } from "@/lib/api/client";
import { useToast } from "@/components/Toast";
import { errorCode } from "@/lib/generation/cards";
import { buildRefineRequest } from "./style";

export type RefineStatus = "idle" | "refining" | "done" | "error";

export interface RefineResult {
  original: string;
  refined: string;
}

export interface UseRefine {
  status: RefineStatus;
  result: RefineResult | null;
  // 回炉重写某段（可选改写指令）→ 返回 {original, refined} 或 null（失败）。
  refine: (
    projectId: string,
    chapterNo: number,
    segment: string,
    instruction?: string,
  ) => Promise<RefineResult | null>;
  // 取消在途回炉（段切换/卸载时调用）——不触碰 state，安全用于 effect 清理。
  abort: () => void;
  reset: () => void;
}

// 回炉（POST .../refine）：同步返回新旧 diff，不写库（不变量#3）。
// 503 LLM_UNAVAILABLE（无凭据）优雅提示去设置；其余失败 toast。
export function useRefine(): UseRefine {
  const [status, setStatus] = useState<RefineStatus>("idle");
  const [result, setResult] = useState<RefineResult | null>(null);
  const controllerRef = useRef<AbortController | null>(null);
  const toast = useToast();

  const refine = useCallback<UseRefine["refine"]>(
    async (projectId, chapterNo, segment, instruction) => {
      // 取消上一次在途请求，换新 controller（段切换竞态防护，CR-H12）。
      controllerRef.current?.abort();
      const controller = new AbortController();
      controllerRef.current = controller;
      setStatus("refining");
      setResult(null);
      try {
        const { data, error } = await api.POST(
          "/projects/{project_id}/chapters/{chapter_no}/refine",
          {
            params: {
              path: { project_id: projectId, chapter_no: chapterNo },
            },
            body: buildRefineRequest(segment, instruction),
            signal: controller.signal,
          },
        );
        // 已被后续请求/卸载中止：丢弃迟到响应，不写状态。
        if (controller.signal.aborted) return null;
        if (error || !data) {
          setStatus("error");
          const code = errorCode(error);
          toast(
            code === "LLM_UNAVAILABLE"
              ? "未配置提供商，请先去设置页连一家。"
              : "回炉失败，请稍后重试。",
            "error",
          );
          return null;
        }
        const outcome: RefineResult = {
          original: data.original,
          refined: data.refined,
        };
        setResult(outcome);
        setStatus("done");
        return outcome;
      } catch {
        // 主动中止（abort）触发的异常不该报错 toast。
        if (controller.signal.aborted) return null;
        setStatus("error");
        toast("回炉请求异常，请检查网络。", "error");
        return null;
      }
    },
    [toast],
  );

  // 仅取消在途请求，不触碰 state——可安全用于 effect 清理 / 卸载。
  const abort = useCallback((): void => {
    controllerRef.current?.abort();
    controllerRef.current = null;
  }, []);

  const reset = useCallback((): void => {
    controllerRef.current?.abort();
    controllerRef.current = null;
    setStatus("idle");
    setResult(null);
  }, []);

  return { status, result, refine, abort, reset };
}
