/**
 * 充值弹窗组件
 * ==============
 *
 * 微信支付 Native（扫码）充值流程：
 * 选择金额 → 下单获取 code_url → 生成二维码 → 温和轮询 / 用户点击【我已支付】 → 到账提示
 */

import { useEffect, useRef, useState, useCallback } from 'react';
import QRCode from 'qrcode';
import Modal from '../Modal/Modal';
import { pointsApi } from '../../api/modules/points';
import { toast } from '../../store/uiStore';
import './RechargeModal.css';

interface RechargeModalProps {
  open: boolean;
  onClose: () => void;
  onRechargeSuccess?: () => void;
}

type RechargeStep = 'select' | 'qrcode' | 'success' | 'error';

interface AmountOption {
  price: number; // 人民币（分）
  points: number;
  label?: string;
  validityDays: number; // 积分有效期（天），0 表示永久有效
}

const POLLING_INTERVAL = 5000; // 5 秒（温和轮询，减少请求）

export default function RechargeModal({
  open,
  onClose,
  onRechargeSuccess,
}: RechargeModalProps) {
  const [step, setStep] = useState<RechargeStep>('select');
  const [options, setOptions] = useState<AmountOption[]>([]);
  const [optionsError, setOptionsError] = useState('');
  const [selectedOption, setSelectedOption] = useState<AmountOption | null>(null);
  const [qrcodeDataUrl, setQrcodeDataUrl] = useState<string>('');
  const orderIdRef = useRef<number>(0);
  const expireAtRef = useRef<number>(0); // 二维码过期时间戳（毫秒）
  const [countdown, setCountdown] = useState<string>('');
  const [isLoading, setIsLoading] = useState(false);
  const [isLoadingOptions, setIsLoadingOptions] = useState(false);
  const [isExpired, setIsExpired] = useState(false);
  const [errorMsg, setErrorMsg] = useState('');

  const pollTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const countdownTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const onRechargeSuccessRef = useRef(onRechargeSuccess);
  onRechargeSuccessRef.current = onRechargeSuccess;

  // 清理所有定时器
  const clearTimers = useCallback(() => {
    if (pollTimerRef.current) {
      clearInterval(pollTimerRef.current);
      pollTimerRef.current = null;
    }
    if (countdownTimerRef.current) {
      clearInterval(countdownTimerRef.current);
      countdownTimerRef.current = null;
    }
  }, []);

  // 弹窗关闭时重置状态
  useEffect(() => {
    if (!open) {
      clearTimers();
      // 延迟重置，避免关闭动画期间状态突变
      const timer = setTimeout(() => {
        setStep('select');
        setSelectedOption(null);
        setQrcodeDataUrl('');
        orderIdRef.current = 0;
        expireAtRef.current = 0;
        setOptions([]);
        setOptionsError('');
        setIsLoadingOptions(false);
        setIsExpired(false);
        setCountdown('');
        setErrorMsg('');
      }, 300);
      return () => clearTimeout(timer);
    }
  }, [open, clearTimers]);

  // 组件卸载时清理
  useEffect(() => {
    return () => clearTimers();
  }, [clearTimers]);

  // 弹窗打开时加载充值档位配置
  useEffect(() => {
    if (open && step === 'select' && options.length === 0 && !isLoadingOptions) {
      setIsLoadingOptions(true);
      pointsApi.getRechargeOptions()
        .then(data => {
          setOptions(data.map(o => ({ price: o.price, points: o.points, label: o.label || undefined, validityDays: o.validityDays ?? 180 })));
          setIsLoadingOptions(false);
        })
        .catch(e => {
          console.error('[Recharge] 加载充值档位失败:', e);
          setOptionsError('加载充值选项失败，请稍后重试');
          setIsLoadingOptions(false);
        });
    }
  }, [open, step, options.length, isLoadingOptions]);

  // 查询支付状态（轮询或手动触发共用）
  const queryPaymentStatus = useCallback(
    async (orderId: number, isManual: boolean = false): Promise<boolean> => {
      try {
        const status = await pointsApi.queryRechargeStatus(orderId);

        if (status.status === 'paid') {
          clearTimers();
          setStep('success');
          // 充值成功通过弹窗展示，不再显示 toast
          onRechargeSuccessRef.current?.();
          return true;
        } else if (status.status === 'closed' || status.status === 'failed') {
          clearTimers();
          setStep('error');
          setErrorMsg('订单已关闭或支付失败，请重新下单');
          return true;
        }
        // pending 状态：手动查询时给用户提示，轮询时静默继续
        if (isManual) {
          toast.info('订单仍在处理中，请确认微信支付是否已完成');
        }
        return false;
      } catch (e) {
        console.error('[Recharge] 查询支付状态失败:', e);
        if (isManual) {
          toast.error(`查询失败: ${e instanceof Error ? e.message : '请稍后重试'}`);
        }
        return false;
      }
    },
    [clearTimers],
  );

  // 开始轮询 + 倒计时
  const startPolling = useCallback(
    (targetOrderId: number) => {
      // 轮询：每 5 秒查一次，直到过期
      pollTimerRef.current = setInterval(async () => {
        // 已过期，停止轮询，显示遮罩
        if (Date.now() >= expireAtRef.current) {
          clearTimers();
          setCountdown('00:00');
          setIsExpired(true);
          return;
        }
        await queryPaymentStatus(targetOrderId);
      }, POLLING_INTERVAL);

      // 倒计时显示
      countdownTimerRef.current = setInterval(() => {
        const remaining = expireAtRef.current - Date.now();
        if (remaining <= 0) {
          clearTimers();
          setCountdown('00:00');
          setIsExpired(true);
          return;
        }
        const minutes = Math.floor(remaining / 60000);
        const seconds = Math.floor((remaining % 60000) / 1000);
        setCountdown(`${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);
      }, 1000);
    },
    [clearTimers, queryPaymentStatus],
  );

  // 用户点击【我已支付】手动查询
  const handleQueryPayment = async () => {
    const orderId = orderIdRef.current;
    if (!orderId) {return;}

    // 二维码已过期，明确提示用户
    if (isExpired || Date.now() >= expireAtRef.current) {
      clearTimers();
      setIsExpired(true);
      toast.info('二维码已过期，请点击刷新二维码或重新下单');
      return;
    }

    setIsLoading(true);
    await queryPaymentStatus(orderId, true);
    setIsLoading(false);
  };

  // 刷新二维码（过期后重新下单）
  const handleRefreshQrcode = async () => {
    if (!selectedOption) {return;}
    setIsExpired(false);
    setQrcodeDataUrl('');
    setCountdown('');
    orderIdRef.current = 0;
    expireAtRef.current = 0;
    await handleConfirm();
  };

  // 确认充值
  const handleConfirm = async () => {
    if (!selectedOption) {
      toast.warning('请选择充值金额');
      return;
    }

    setIsLoading(true);
    try {
      const order = await pointsApi.createRechargeOrder(
        selectedOption.points,
        selectedOption.price,
      );

      if (!order.codeUrl) {
        throw new Error('未获取到支付二维码');
      }

      orderIdRef.current = order.orderId;
      expireAtRef.current = order.expireAt ? new Date(order.expireAt).getTime() : Date.now() + 2 * 60 * 1000;

      // 生成二维码图片
      const dataUrl = await QRCode.toDataURL(order.codeUrl, {
        width: 240,
        margin: 2,
        color: {
          dark: '#000000',
          light: '#ffffff',
        },
      });
      setQrcodeDataUrl(dataUrl);
      setStep('qrcode');

      // 开始温和轮询（同时保留【我已支付】手动兜底）
      startPolling(orderIdRef.current);
    } catch (e) {
      console.error('[Recharge] 创建订单失败:', e);
      toast.error(`创建订单失败: ${e instanceof Error ? e.message : '请稍后重试'}`);
    } finally {
      setIsLoading(false);
    }
  };

  // 格式化金额（分 → 元）
  const formatPrice = (priceInFen: number) => {
    const yuan = priceInFen / 100;
    return `¥${yuan < 1 ? yuan.toFixed(2) : yuan.toFixed(0)}`;
  };

  // 渲染金额选择
  const renderSelectStep = () => (
    <>
      <div className="recharge-amount-section">
        <div className="recharge-amount-label">选择充值金额</div>
        <div className="recharge-amount-grid">
          {isLoadingOptions || options.length === 0
            ? Array.from({ length: 4 }).map((_, i) => (
                <div key={`skeleton-${i}`} className="recharge-amount-card skeleton">
                  <div className="skeleton-price" />
                  <div className="skeleton-points" />
                  <div className="skeleton-validity" />
                </div>
              ))
            : options.map(option => (
                <div
                  key={option.price}
                  className={`recharge-amount-card ${selectedOption?.price === option.price ? 'selected' : ''}`}
                  onClick={() => setSelectedOption(option)}
                >
                  {option.label && <span className="tag">{option.label}</span>}
                  <div className="price">{formatPrice(option.price)}</div>
                  <div className="points">{option.points} 积分</div>
                  <div className="validity">{option.validityDays === 0 ? '永久有效' : `${option.validityDays} 天内有效`}</div>
                </div>
              ))}
        </div>
        {optionsError && <div className="recharge-options-error">{optionsError}</div>}
      </div>

      <div className="recharge-order-info">
        <span className="label">实付金额</span>
        <span className={`value ${selectedOption ? '' : 'placeholder'}`}>
          {selectedOption ? formatPrice(selectedOption.price) : '请选择充值金额'}
        </span>
      </div>

      <div className="recharge-modal-footer">
        <button className="btn btn-ghost" onClick={onClose}>
          取消
        </button>
        <button
          className="btn btn-primary"
          onClick={handleConfirm}
          disabled={!selectedOption || isLoading || options.length === 0}
        >
          {isLoading ? '创建订单中...' : '确认充值'}
        </button>
      </div>
    </>
  );

  // 渲染二维码
  const renderQrcodeStep = () => (
    <>
      <div className="recharge-order-info">
        <span className="label">充值 {selectedOption?.points} 积分</span>
        <span className="value">{formatPrice(selectedOption?.price || 0)}</span>
      </div>

      <div className="recharge-qrcode-section">
        <div className={`recharge-qrcode-wrapper ${isExpired ? 'expired' : ''}`}>
          <img src={qrcodeDataUrl} alt="微信支付二维码" />
          {isExpired && (
            <div className="recharge-qrcode-overlay">
              <div className="recharge-qrcode-overlay-text">二维码已过期</div>
              <button
                className="recharge-refresh-btn"
                onClick={handleRefreshQrcode}
                title="刷新二维码"
              >
                <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <polyline points="23 4 23 10 17 10" />
                  <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10" />
                </svg>
              </button>
            </div>
          )}
        </div>
        <div className="recharge-qrcode-tip">
          <svg
            width="16"
            height="16"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
          >
            <path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2zm0 18a8 8 0 1 1 8-8 8 8 0 0 1-8 8z" />
            <path d="M12 6v6l4 2" />
          </svg>
          请使用微信扫一扫完成支付
        </div>
        <div className="recharge-qrcode-countdown">
          {countdown ? (
            <>二维码将在 <span>{countdown}</span> 后过期</>
          ) : (
            <span style={{ visibility: 'hidden' }}>占位</span>
          )}
        </div>
        <div className="recharge-qrcode-actions">
          <button
            className="btn btn-primary"
            onClick={handleQueryPayment}
            disabled={isLoading || isExpired}
          >
            {isLoading ? '查询中...' : isExpired ? '二维码已过期' : '我已支付'}
          </button>
          <button
            className="btn btn-ghost"
            onClick={() => {
              setStep('select');
              setSelectedOption(null);
              setErrorMsg('');
            }}
          >
            重新选择
          </button>
        </div>
      </div>
    </>
  );

  // 渲染成功
  const renderSuccessStep = () => (
    <div className="recharge-success-section">
      <div className="recharge-success-icon">
        <svg
          width="32"
          height="32"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="3"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <polyline points="20 6 9 17 4 12" />
        </svg>
      </div>
      <div className="recharge-success-title">充值成功</div>
      <div className="recharge-success-desc">
        {selectedOption?.points} 积分已到账，可以开始创作了
      </div>

      <div className="recharge-modal-footer" style={{ marginTop: 'var(--spacing-xl)' }}>
        <button className="btn btn-primary" onClick={onClose}>
          知道了
        </button>
      </div>
    </div>
  );

  // 渲染错误
  const renderErrorStep = () => (
    <div className="recharge-error-section">
      <div className="recharge-error-icon">
        <svg
          width="32"
          height="32"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <circle cx="12" cy="12" r="10" />
          <line x1="15" y1="9" x2="9" y2="15" />
          <line x1="9" y1="9" x2="15" y2="15" />
        </svg>
      </div>
      <div className="recharge-error-title">支付未确认</div>
      <div className="recharge-error-desc">{errorMsg}</div>

      <div className="recharge-modal-footer" style={{ marginTop: 'var(--spacing-xl)' }}>
        <button className="btn btn-ghost" onClick={onClose}>
          关闭
        </button>
        <button
          className="btn btn-primary"
          onClick={() => {
            setStep('select');
            setSelectedOption(null);
            setErrorMsg('');
          }}
        >
          重新下单
        </button>
      </div>
    </div>
  );

  const stepTitles: Record<RechargeStep, string> = {
    select: '积分充值',
    qrcode: '微信支付',
    success: '充值成功',
    error: '支付未确认',
  };

  return (
    <Modal
      open={open}
      onClose={onClose}
      title={step === 'qrcode' || step === 'select' || step === 'success' || step === 'error' ? '' : stepTitles[step]}
      width="420px"
      centerTitle={step === 'success' || step === 'error'}
    >
      <div className="recharge-modal-body">
        {step === 'select' && renderSelectStep()}
        {step === 'qrcode' && renderQrcodeStep()}
        {step === 'success' && renderSuccessStep()}
        {step === 'error' && renderErrorStep()}
      </div>
    </Modal>
  );
}
