"use client";

import { useCallback, useState } from "react";

import { api } from "@/lib/api/client";
import { useToast } from "@/components/Toast";
import type { CharacterCardView } from "@/lib/api/types";
import {
  buildCharacterGenerateRequest,
  buildCharacterIngestRequest,
  extractIngestConflicts,
  generationErrorMessage,
  type IngestConflicts,
} from "./cards";

export type CharacterGenStatus = "idle" | "generating" | "preview" | "error";
export type IngestStatus = "idle" | "ingesting" | "conflict" | "done" | "error";

export interface CharacterGenInput {
  projectId: string;
  brief: string;
  count: number;
  role?: string | null;
  // 群像按定位配比（⑦）；在场时后端把 count 定为各值之和，忽略 count/role。
  roleMix?: Readonly<Record<string, number>> | null;
}

export interface UseCharacterGen {
  genStatus: CharacterGenStatus;
  cards: CharacterCardView[];
  ingestStatus: IngestStatus;
  // 409 冲突详情（待作者裁决）；裁决后带 acknowledge 重发。
  conflicts: IngestConflicts | null;
  created: string[];
  generate: (input: CharacterGenInput) => Promise<void>;
  // 入库选中卡；acknowledge 用于过 409（已查看冲突后重发）。
  ingest: (
    projectId: string,
    cards: readonly CharacterCardView[],
    acknowledge?: boolean,
  ) => Promise<boolean>;
  reset: () => void;
}

// 角色生成器（UX §6.6）：生成预览 → 作者选/改 → 入库（处理 409 裁决流）。
export function useCharacterGen(): UseCharacterGen {
  const [genStatus, setGenStatus] = useState<CharacterGenStatus>("idle");
  const [cards, setCards] = useState<CharacterCardView[]>([]);
  const [ingestStatus, setIngestStatus] = useState<IngestStatus>("idle");
  const [conflicts, setConflicts] = useState<IngestConflicts | null>(null);
  const [created, setCreated] = useState<string[]>([]);
  const toast = useToast();

  const generate = useCallback<UseCharacterGen["generate"]>(
    async ({ projectId, brief, count, role, roleMix }) => {
      setGenStatus("generating");
      setCards([]);
      setConflicts(null);
      setIngestStatus("idle");
      try {
        const { data, error } = await api.POST(
          "/projects/{project_id}/characters/generate",
          {
            params: { path: { project_id: projectId } },
            body: buildCharacterGenerateRequest(brief, count, role, roleMix),
          },
        );
        if (error || !data) {
          setGenStatus("error");
          toast(generationErrorMessage(error), "error");
          return;
        }
        setCards(data.cards ?? []);
        setGenStatus("preview");
      } catch {
        setGenStatus("error");
        toast("生成请求异常，请检查网络。", "error");
      }
    },
    [toast],
  );

  const ingest = useCallback<UseCharacterGen["ingest"]>(
    async (projectId, ingestCards, acknowledge = false) => {
      if (ingestCards.length === 0) {
        toast("请至少选择一张角色卡。", "error");
        return false;
      }
      setIngestStatus("ingesting");
      try {
        const { data, error } = await api.POST(
          "/projects/{project_id}/characters",
          {
            params: { path: { project_id: projectId } },
            body: buildCharacterIngestRequest(ingestCards, acknowledge),
          },
        );
        if (error || !data) {
          const conflict = extractIngestConflicts(error);
          if (conflict) {
            // 409 CONFLICT_UNRESOLVED：展示冲突让作者裁决，再带 acknowledge 重发。
            setConflicts(conflict);
            setIngestStatus("conflict");
            return false;
          }
          setIngestStatus("error");
          toast(generationErrorMessage(error), "error");
          return false;
        }
        setCreated(data.created ?? []);
        setConflicts(null);
        setIngestStatus("done");
        toast(`已入库 ${data.created?.length ?? 0} 个角色`, "success");
        if (data.rejected_tables && data.rejected_tables.length > 0) {
          toast(`越权写表被丢弃：${data.rejected_tables.join("、")}`, "info");
        }
        return true;
      } catch {
        setIngestStatus("error");
        toast("入库请求异常，请检查网络。", "error");
        return false;
      }
    },
    [toast],
  );

  const reset = useCallback((): void => {
    setGenStatus("idle");
    setCards([]);
    setIngestStatus("idle");
    setConflicts(null);
    setCreated([]);
  }, []);

  return {
    genStatus,
    cards,
    ingestStatus,
    conflicts,
    created,
    generate,
    ingest,
    reset,
  };
}
