import { useCallback, useRef, useState } from 'react';
import type { XAgentCommand_v0_9 } from '@ant-design/x-card';

/**
 * 提交状态管理：收敛 DynamicForm / DynamicReview 中重复的
 * submitting / submitted / error 状态与「防重复提交 + 失败可重试」逻辑。
 *
 * 用法：
 *   const { submitting, submitted, error, run } = useSubmissionState();
 *   const handleSubmit = (values) => run(async () => { await onSubmit(values); });
 */
export function useSubmissionState() {
  const [submitting, setSubmitting] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const submittingRef = useRef(false);

  const run = useCallback(async (task: () => Promise<void> | void) => {
    if (submittingRef.current) return;
    submittingRef.current = true;
    setSubmitting(true);
    setError(null);
    try {
      await task();
      setSubmitted(true);
    } catch (reason) {
      setError(reason instanceof Error ? reason.message : '提交失败，请稍后重试');
    } finally {
      submittingRef.current = false;
      setSubmitting(false);
    }
  }, []);

  const reset = useCallback(() => {
    setSubmitted(false);
    setError(null);
  }, []);

  return { submitting, submitted, error, run, reset };
}

/**
 * A2UI surface 的 XCard commands 增量更新生命周期：
 * 每个 surface 只创建一次，后续通过 updateDataModel / updateComponents 增量更新。
 *
 * 用法：
 *   const { pushCommands } = useXCardSurface(surfaceId);
 *   useEffect(() => {
 *     pushCommands([
 *       { version: 'v0.9', createSurface: { surfaceId, catalogId } },
 *       { version: 'v0.9', updateDataModel: { surfaceId, path: '/x', value } },
 *       { version: 'v0.9', updateComponents: { surfaceId, components } },
 *     ]);
 *   }, [value]);
 */
export function useXCardSurface(surfaceId: string) {
  const commandsRef = useRef<XAgentCommand_v0_9[]>([]);
  const [commands, setCommands] = useState<XAgentCommand_v0_9[]>([]);
  const idRef = useRef<string>('');

  const pushCommands = useCallback(
    (cmds: XAgentCommand_v0_9[]) => {
      if (cmds.length === 0) return;
      // 同一 surface 的 createSurface 命令只允许出现一次，自动去重
      const hasSurface = commandsRef.current.some(
        (c) => 'createSurface' in c && c.createSurface.surfaceId === surfaceId,
      );
      const filtered = hasSurface
        ? cmds.filter((c) => !('createSurface' in c))
        : cmds;
      commandsRef.current = [...commandsRef.current, ...filtered];
      setCommands([...commandsRef.current]);
    },
    [surfaceId],
  );

  const surfaceKey = surfaceId;
  if (idRef.current !== surfaceKey) {
    // 组件复用到新 surface 时，清空历史命令重新初始化
    commandsRef.current = [];
    idRef.current = surfaceKey;
  }

  return { commands, pushCommands };
}
