/**
 * 积分检查 Hook
 * ============
 *
 * 统一封装积分预检、402 错误捕获和 ConfirmModal 弹窗逻辑。
 *
 * 使用示例：
 * ```tsx
 * const { checkBalance, handleError, PointsModal } = usePointsCheck();
 *
 * // 操作前预检
 * const ok = await checkBalance(5, '脚本生成');
 * if (!ok) return;
 *
 * try {
 *   await api.createTask(...);
 * } catch (err) {
 *   if (handleError(err, '脚本生成', 5)) return;
 *   throw err; // 非积分不足错误，继续抛给上层
 * }
 *
 * // JSX 底部渲染弹窗
 * <PointsModal />
 * ```
 */

import { useState, useCallback } from 'react';
import { usePointStore } from '../store';
import ConfirmModal from '../components/Modal/ConfirmModal';
import RechargeModal from '../components/RechargeModal/RechargeModal';

export function usePointsCheck() {
  const [showPointsModal, setShowPointsModal] = useState(false);
  const [modalDescription, setModalDescription] = useState('');
  const showRechargeModal = usePointStore((state) => state.showRechargeModal);
  const setShowRechargeModal = usePointStore((state) => state.setShowRechargeModal);
  const fetchBalance = usePointStore((state) => state.fetchBalance);

  /**
   * 检查余额是否足够，不足时自动弹出 ConfirmModal
   * @param points 需要的积分
   * @param bizName 业务名称（如"脚本生成"）
   * @param strict 是否严格检查（默认 true）
   *   - true：预估积分 > 余额时阻止（视频生成等确定消耗场景）
   *   - false：仅余额 <= 0 时阻止（TTS 等不确定消耗场景，允许欠费）
   * @returns true=余额足够，false=不足并已弹窗
   */
  const checkBalance = useCallback(
    async (points: number | { min: number; max: number }, _bizName: string, strict: boolean = true): Promise<boolean> => {
      await fetchBalance();
      const balance = usePointStore.getState().balance;
      const maxPoints = typeof points === 'number' ? points : points.max;

      // 余额为负或零时，任何业务都阻止
      if (balance <= 0) {
        setModalDescription(`余额不足（${balance} 积分），请先充值`);
        setShowPointsModal(true);
        return false;
      }

      // 严格模式：预估 > 余额时阻止（确定消耗场景）
      if (strict && balance < maxPoints) {
        const pointsText = typeof points === 'number'
          ? `${points}`
          : `${(points as { min: number; max: number }).min}~${(points as { min: number; max: number }).max}`;
        setModalDescription(`预计消耗 ${pointsText} 积分，当前余额 ${balance} 积分`);
        setShowPointsModal(true);
        return false;
      }

      return true;
    },
    [fetchBalance],
  );

  /**
   * 从 catch 的错误中判断是否是积分不足（402），是则弹窗
   * @param error catch 到的错误
   * @param bizName 业务名称
   * @param requiredPoints 需要的积分（可选，用于显示）
   * @returns true=已识别为积分不足并弹窗，false=不是积分不足
   */
  const handleError = useCallback(
    (error: unknown, _bizName: string, _requiredPoints?: number): boolean => {
      const msg = error instanceof Error ? error.message : String(error);
      if (msg.includes('402') || msg.includes('积分不足')) {
        setModalDescription(`预计消耗 ${_requiredPoints || '?'} 积分`);
        setShowPointsModal(true);
        return true;
      }
      return false;
    },
    [],
  );

  /** 弹窗组件，在页面 JSX 底部渲染 */
  const PointsModal = useCallback(() => {
    return (
      <>
        <ConfirmModal
          open={showPointsModal}
          type="warning"
          title="积分不足"
          description={modalDescription}
          confirmText="立即充值"
          cancelText="稍后再说"
          confirmButtonType="danger"
          onConfirm={() => {
            setShowPointsModal(false);
            setShowRechargeModal(true);
          }}
          onCancel={() => setShowPointsModal(false)}
          onClose={() => setShowPointsModal(false)}
        />
        <RechargeModal
          open={showRechargeModal}
          onClose={() => setShowRechargeModal(false)}
          onRechargeSuccess={() => {
            fetchBalance();
            setShowPointsModal(false);
          }}
        />
      </>
    );
  }, [showPointsModal, modalDescription, showRechargeModal, fetchBalance, setShowRechargeModal]);

  return { checkBalance, handleError, PointsModal };
}
