import { useState, useCallback, useRef, useEffect } from 'react';
import Taro from '@tarojs/taro';
import {
  confirmWechatQRLogin,
  parseQRContent
} from '@/api/passport/qr-login';
import { getShopGiftByCode, updateShopGift, decryptQrData } from "@/api/shop/shopGift";
import { useUser } from "@/hooks/useUser";
import { isValidJSON } from "@/utils/jsonUtils";
import dayjs from 'dayjs';

/**
 * 统一扫码状态
 */
export enum UnifiedScanState {
  IDLE = 'idle',           // 空闲状态
  SCANNING = 'scanning',   // 正在扫码
  PROCESSING = 'processing', // 正在处理
  SUCCESS = 'success',     // 处理成功
  ERROR = 'error'          // 处理失败
}

/**
 * 扫码类型
 */
export enum ScanType {
  LOGIN = 'login',         // 登录二维码
  VERIFICATION = 'verification', // 核销二维码
  UNKNOWN = 'unknown'      // 未知类型
}

/**
 * 统一扫码结果
 */
export interface UnifiedScanResult {
  type: ScanType;
  data: any;
  message: string;
}

/**
 * 统一扫码Hook
 * 可以处理登录和核销两种类型的二维码
 */
export function useUnifiedQRScan() {
  const { isAdmin } = useUser();
  const [state, setState] = useState<UnifiedScanState>(UnifiedScanState.IDLE);
  const [error, setError] = useState<string>('');
  const [result, setResult] = useState<UnifiedScanResult | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [scanType, setScanType] = useState<ScanType>(ScanType.UNKNOWN);

  // 用于取消操作的引用
  const cancelRef = useRef<boolean>(false);

  /**
   * 重置状态
   */
  const reset = useCallback(() => {
    setState(UnifiedScanState.IDLE);
    setError('');
    setResult(null);
    setIsLoading(false);
    setScanType(ScanType.UNKNOWN);
    cancelRef.current = false;
  }, []);

  /**
   * 检测二维码类型
   */
  const detectScanType = useCallback((scanResult: string): ScanType => {
    try {
      // 1. 检查是否为JSON格式（核销二维码）
      if (isValidJSON(scanResult)) {
        const json = JSON.parse(scanResult);
        if (json.businessType === 'gift' && json.token && json.data) {
          return ScanType.VERIFICATION;
        }
      }

      // 2. 检查是否为登录二维码
      const loginToken = parseQRContent(scanResult);
      if (loginToken) {
        return ScanType.LOGIN;
      }

      // 3. 检查是否为纯文本核销码（6位数字）
      if (/^\d{6}$/.test(scanResult.trim())) {
        return ScanType.VERIFICATION;
      }

      return ScanType.UNKNOWN;
    } catch (error) {
      console.error('检测二维码类型失败:', error);
      return ScanType.UNKNOWN;
    }
  }, []);

  /**
   * 处理登录二维码
   */
  const handleLoginQR = useCallback(async (scanResult: string): Promise<UnifiedScanResult> => {
    const userId = Taro.getStorageSync('UserId');
    if (!userId) {
      throw new Error('请先登录小程序');
    }

    const token = parseQRContent(scanResult);
    if (!token) {
      throw new Error('无效的登录二维码');
    }

    const confirmResult = await confirmWechatQRLogin(token, parseInt(userId));
    if (confirmResult.status === 'confirmed') {
      return {
        type: ScanType.LOGIN,
        data: confirmResult,
        message: '登录成功'
      };
    } else {
      throw new Error(confirmResult.message || '登录确认失败');
    }
  }, []);

  /**
   * 处理核销二维码
   */
  const handleVerificationQR = useCallback(async (scanResult: string): Promise<UnifiedScanResult> => {
    if (!isAdmin()) {
      throw new Error('您没有核销权限');
    }

    let code = '';

    // 判断是否为加密的JSON格式
    if (isValidJSON(scanResult)) {
      const json = JSON.parse(scanResult);
      if (json.businessType === 'gift' && json.token && json.data) {
        // 解密获取核销码
        const decryptedData = await decryptQrData({
          token: json.token,
          encryptedData: json.data
        });

        if (decryptedData) {
          code = decryptedData.toString();
        } else {
          throw new Error('解密失败');
        }
      }
    } else {
      // 直接使用扫码结果作为核销码
      code = scanResult.trim();
    }

    if (!code) {
      throw new Error('无法获取有效的核销码');
    }

    // 验证核销码
    const gift = await getShopGiftByCode(code);

    if (!gift) {
      throw new Error('核销码无效');
    }

    if (gift.status === 1) {
      throw new Error('此礼品码已使用');
    }

    if (gift.status === 2) {
      throw new Error('此礼品码已失效');
    }

    if (gift.userId === 0) {
      throw new Error('此礼品码未认领');
    }

    // 执行核销
    await updateShopGift({
      ...gift,
      status: 1,
      operatorUserId: Number(Taro.getStorageSync('UserId')) || 0,
      takeTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      verificationTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
    });

    return {
      type: ScanType.VERIFICATION,
      data: gift,
      message: '核销成功'
    };
  }, [isAdmin]);

  /**
   * 开始扫码
   */
  const startScan = useCallback(async (): Promise<UnifiedScanResult | null> => {
    try {
      reset();
      setState(UnifiedScanState.SCANNING);

      // 调用扫码API
      const scanResult = await new Promise<string>((resolve, reject) => {
        Taro.scanCode({
          onlyFromCamera: true,
          scanType: ['qrCode'],
          success: (res) => {
            if (res.result) {
              resolve(res.result);
            } else {
              reject(new Error('扫码结果为空'));
            }
          },
          fail: (err) => {
            reject(new Error(err.errMsg || '扫码失败'));
          }
        });
      });

      // 检查是否被取消
      if (cancelRef.current) {
        return null;
      }

      // 检测二维码类型
      const type = detectScanType(scanResult);
      setScanType(type);

      if (type === ScanType.UNKNOWN) {
        throw new Error('不支持的二维码类型');
      }

      // 开始处理
      setState(UnifiedScanState.PROCESSING);
      setIsLoading(true);

      let result: UnifiedScanResult;

      switch (type) {
        case ScanType.LOGIN:
          result = await handleLoginQR(scanResult);
          break;
        case ScanType.VERIFICATION:
          result = await handleVerificationQR(scanResult);
          break;
        default:
          throw new Error('未知的扫码类型');
      }

      if (cancelRef.current) {
        return null;
      }

      setState(UnifiedScanState.SUCCESS);
      setResult(result);

      // 显示成功提示
      Taro.showToast({
        title: result.message,
        icon: 'success',
        duration: 2000
      });

      return result;

    } catch (err: any) {
      if (!cancelRef.current) {
        setState(UnifiedScanState.ERROR);
        const errorMessage = err.message || '处理失败';
        setError(errorMessage);

        // 显示错误提示
        Taro.showToast({
          title: errorMessage,
          icon: 'error',
          duration: 3000
        });
      }
      return null;
    } finally {
      setIsLoading(false);
    }
  }, [reset, detectScanType, handleLoginQR, handleVerificationQR]);

  /**
   * 取消扫码
   */
  const cancel = useCallback(() => {
    cancelRef.current = true;
    reset();
  }, [reset]);

  /**
   * 检查是否可以进行扫码
   */
  const canScan = useCallback(() => {
    const userId = Taro.getStorageSync('UserId');
    const accessToken = Taro.getStorageSync('access_token');
    return !!(userId && accessToken);
  }, []);

  // 组件卸载时取消操作
  useEffect(() => {
    return () => {
      cancelRef.current = true;
    };
  }, []);

  return {
    // 状态
    state,
    error,
    result,
    isLoading,
    scanType,

    // 方法
    startScan,
    cancel,
    reset,
    canScan,

    // 便捷状态判断
    isIdle: state === UnifiedScanState.IDLE,
    isScanning: state === UnifiedScanState.SCANNING,
    isProcessing: state === UnifiedScanState.PROCESSING,
    isSuccess: state === UnifiedScanState.SUCCESS,
    isError: state === UnifiedScanState.ERROR
  };
}
