"use client";

import { useCallback, useState } from "react";

import { api } from "@/lib/api/client";
import { useToast } from "@/components/Toast";
import type { RuleView } from "@/lib/api/types";
import { buildRuleCreateRequest, hasUsableContent, type RuleLevel } from "./rules";

export interface UseRules {
  items: RuleView[];
  // 正在新增（仅冻结新增表单，不影响删除）。
  adding: boolean;
  // 正在删除的那一条 id（仅冻结该行删除按钮，整页其余照常可操作）。
  deletingId: string | null;
  // 新增一条规则（乐观追加 + 失败回滚 + Toast）。
  add: (
    projectId: string,
    level: RuleLevel,
    content: string,
  ) => Promise<boolean>;
  // 删除一条规则（乐观移除 + 失败回滚 + Toast）。
  remove: (projectId: string, ruleId: string) => Promise<boolean>;
}

// 规则页（UX §7）：列出 + 新增规则。乐观追加，失败回滚（仿 useForeshadow）。
// add 与 remove 用各自独立的进行中标志，避免删一条就冻结整页。
export function useRules(initial: RuleView[]): UseRules {
  const [items, setItems] = useState<RuleView[]>(initial);
  const [adding, setAdding] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const toast = useToast();

  const add = useCallback<UseRules["add"]>(
    async (projectId, level, content) => {
      if (!hasUsableContent(content)) {
        toast("请填写规则正文。", "error");
        return false;
      }
      const snapshot = items;
      // 乐观项需一个临时 id（删除 handle 之前）；服务端返回后被权威行替换。
      const optimistic: RuleView = {
        id: crypto.randomUUID(),
        level,
        content: content.trim(),
      };
      setItems((prev) => [...prev, optimistic]);
      setAdding(true);
      try {
        const { data, error } = await api.POST(
          "/projects/{project_id}/rules",
          {
            params: { path: { project_id: projectId } },
            body: buildRuleCreateRequest(level, content),
          },
        );
        if (error || !data) {
          setItems(snapshot); // 回滚
          toast("新增规则失败，请稍后重试。", "error");
          return false;
        }
        // 用服务端权威行替换乐观行（去掉乐观项、追加返回项）。
        setItems((prev) => [...prev.slice(0, snapshot.length), data]);
        toast("已新增规则", "success");
        return true;
      } finally {
        setAdding(false);
      }
    },
    [items, toast],
  );

  const remove = useCallback<UseRules["remove"]>(
    async (projectId, ruleId) => {
      const snapshot = items;
      setItems((prev) => prev.filter((r) => r.id !== ruleId));
      setDeletingId(ruleId);
      try {
        const { error } = await api.DELETE(
          "/projects/{project_id}/rules/{rule_id}",
          { params: { path: { project_id: projectId, rule_id: ruleId } } },
        );
        if (error) {
          setItems(snapshot); // 回滚
          toast("删除规则失败，请稍后重试。", "error");
          return false;
        }
        toast("已删除规则", "success");
        return true;
      } finally {
        setDeletingId(null);
      }
    },
    [items, toast],
  );

  return { items, adding, deletingId, add, remove };
}
