// ============================================================
// RechargePage — 积分充值表单 + 支付状态跟踪
//
// 通过 PageDispatcher 调度（Modal 容器），导航栏"充值"按钮触发。
// 两阶段视图：
//   form     — 金额选择 → 自定义输入 → 支付方式 → 协议 → 提交
//   pending  — 订单已创建，轮询支付状态，可重新打开支付页面
//   paid     — 支付成功
//   expired  — 订单过期，可重新下单
//   failed   — 支付失败，可重新下单
// ============================================================

import { useState, useMemo, useCallback, useEffect } from 'react';
import {
   Radio,
   InputNumber,
   Button,
   Checkbox,
   Typography,
   App,
   Space,
   Divider,
   theme as antTheme,
   Result,
} from 'antd';
import {
   AlipayOutlined,
   WechatOutlined,
   WalletOutlined,
   DollarOutlined,
} from '@ant-design/icons';

import { useTheme } from '@/components/providers/ThemeProvider';
import { LegalTextModal } from '@/components/ui/LegalTextModal';
import {
   PaymentAPI,
   PAYMENT_METHODS,
   PAYMENT_STATUS,
   getPaymentStatusText,
   type PaymentStatus,
} from '@/services/modules/payments';
import { emit, EVENTS } from '@/utils/bus';

const { Text } = Typography;

// ---------- 常量 ----------

const PRESET_AMOUNTS = [10, 100, 500, 1000, 5000, 10000] as const;

/** 单次充值上限（元） */
const MAX_AMOUNT_YUAN = 100000;

/** 订单状态轮询间隔（毫秒） */
const POLL_INTERVAL_MS = 3000;

/** 页面阶段 */
type RechargePhase = 'form' | PaymentStatus;

// ---------- 组件 ----------

export function RechargePage() {
   const { isDark } = useTheme();
   const { message } = App.useApp();
   const { token } = antTheme.useToken();

   // ======== 表单状态 ========

   const [selectedAmount, setSelectedAmount] = useState<number | null>(null);
   const [customAmount, setCustomAmount] = useState<number | null>(null);
   const [paymentMethod, setPaymentMethod] = useState<string>(PAYMENT_METHODS.Alipay);
   const [agreedToTerms, setAgreedToTerms] = useState(false);
   const [submitting, setSubmitting] = useState(false);
   const [errors, setErrors] = useState<Record<string, string>>({});
   const [legalOpen, setLegalOpen] = useState(false);

   // ======== 订单状态 ========

   const [phase, setPhase] = useState<RechargePhase>('form');
   const [orderId, setOrderId] = useState<string | null>(null);
   const [orderStatus, setOrderStatus] = useState<PaymentStatus | null>(null);
   const [payUrl, setPayUrl] = useState<string | null>(null);

   // ======== 派生值 ========

   /** 最终充值金额（元）：自定义金额优先，否则预设金额，否则 0 */
   const finalAmountYuan = useMemo(() => {
      if (customAmount !== null && customAmount !== undefined) {
         return customAmount;
      }
      return selectedAmount ?? 0;
   }, [customAmount, selectedAmount]);

   /** 最终充值金额（分）：元 × 100，用于 API 调用 */
   const finalAmountCent = finalAmountYuan * 100;

   // ======== 工具函数 ========

   const clearError = useCallback((name: string) => {
      setErrors((prev) => {
         if (!(name in prev)) return prev;
         const next = { ...prev };
         delete next[name];
         return next;
      });
   }, []);

   // ======== 校验 ========

   const validate = useCallback((): Record<string, string> => {
      const errs: Record<string, string> = {};

      if (!finalAmountYuan || finalAmountYuan <= 0) {
         errs.amount = '请选择或输入充值金额';
      } else if (!Number.isInteger(finalAmountYuan) || finalAmountYuan % 10 !== 0) {
         errs.customAmount = '金额必须为 10 的倍数';
      } else if (finalAmountYuan > MAX_AMOUNT_YUAN) {
         errs.customAmount = `单次充值上限为 ${MAX_AMOUNT_YUAN.toLocaleString()} 元`;
      }

      if (!agreedToTerms) {
         errs.agreedToTerms = '请阅读并同意充值协议';
      }

      return errs;
   }, [finalAmountYuan, agreedToTerms]);

   // ======== 支付方式切换 ========

   const handlePaymentChange = useCallback(
      (value: string) => {
         if (value === PAYMENT_METHODS.WeChat) {
            void message.info('微信支付正在接入中，敬请期待');
            return; // 不更新 state，保持支付宝选中
         }
         setPaymentMethod(value);
      },
      [message],
   );

   // ======== 提交流程 ========

   const handleSubmit = useCallback(async () => {
      const validationErrors = validate();
      if (Object.keys(validationErrors).length > 0) {
         setErrors(validationErrors);
         return;
      }

      setSubmitting(true);
      try {
         const res = await PaymentAPI.createOrder({
            amount_cent: finalAmountCent,
            payment_channel: PAYMENT_METHODS.Alipay,
         });

         // 保存订单信息，进入等待支付阶段
         setOrderId(res.id);
         setOrderStatus(PAYMENT_STATUS.Pending);
         setPayUrl(res.pay_url);
         setPhase(PAYMENT_STATUS.Pending);

         window.open(res.pay_url, '_blank');
         void message.success('订单已创建，请在新页面中完成支付');
      } catch (err: unknown) {
         message.error((err as Error)?.message || '创建订单失败，请重试');
      } finally {
         setSubmitting(false);
      }
   }, [finalAmountCent, validate, message]);

   // ======== 订单状态轮询 ========

   useEffect(() => {
      if (phase !== PAYMENT_STATUS.Pending || !orderId) return;

      let timer: ReturnType<typeof setTimeout>;
      let cancelled = false;

      const poll = async () => {
         try {
            const order = await PaymentAPI.getOrderInfo({ order_id: orderId });
            if (cancelled) return;

            const newStatus = order.status;
            setOrderStatus(newStatus);

            if (newStatus === PAYMENT_STATUS.Pending) {
               // 仍待支付 → 继续轮询
               timer = setTimeout(poll, POLL_INTERVAL_MS);
            } else {
               // 终态 → 停止轮询，切换阶段
               setPhase(newStatus);
               if (newStatus === PAYMENT_STATUS.Paid) {
                  void message.success('支付成功，积分已到账');
               }
            }
         } catch {
            // 网络异常 → 延长间隔后继续轮询
            if (!cancelled) timer = setTimeout(poll, POLL_INTERVAL_MS * 2);
         }
      };

      timer = setTimeout(poll, POLL_INTERVAL_MS);
      return () => {
         cancelled = true;
         clearTimeout(timer);
      };
   }, [phase, orderId, message]);

   // ======== 页面锁定（待支付时禁止关闭容器） ========

   useEffect(() => {
      const locked = phase === PAYMENT_STATUS.Pending;
      emit(EVENTS.PAGE_LOCK, { locked });
      // 组件卸载时确保解锁（防止锁定残留）
      return () => {
         if (locked) emit(EVENTS.PAGE_LOCK, { locked: false });
      };
   }, [phase]);

   // ======== 操作回调 ========

   /** 重新下单：回到表单，保留之前填写的金额 */
   const handleRetry = useCallback(() => {
      setPhase('form');
      setOrderId(null);
      setOrderStatus(null);
      setPayUrl(null);
   }, []);

   /** 关闭充值页面 */
   const handleClose = useCallback(() => {
      emit(EVENTS.CLOSE_PAGE);
   }, []);

   // ================================================================
   // 渲染：支付状态视图（非 form 阶段）
   // ================================================================

   if (phase !== 'form') {
      const statusText = orderStatus ? getPaymentStatusText(orderStatus) : '';
      const isPending = phase === PAYMENT_STATUS.Pending;
      const isPaid = phase === PAYMENT_STATUS.Paid;
      const isTerminal = !isPending;

      return (
         <>
            <div style={{ padding: '16px 0' }}>
               <Result
                  status={
                     isPaid
                        ? 'success'
                        : isPending
                           ? 'info'
                           : 'error'
                  }
                  title={
                     isPaid
                        ? '支付成功'
                        : isPending
                           ? `等待支付（${statusText}）`
                           : statusText
                  }
                  subTitle={
                     isPaid
                        ? `已到账积分：${finalAmountYuan.toLocaleString()} 积分`
                        : isPending
                           ? '请在新打开的浏览器页面中完成支付'
                           : undefined
                  }
               >
                  {/* ---- 订单信息卡片 ---- */}
                  {isPending && (
                     <div
                        style={{
                           background: isDark ? '#2E2A5A' : '#F5F3FF',
                           padding: '12px 16px',
                           borderRadius: 8,
                           marginBottom: 16,
                           textAlign: 'left',
                           maxWidth: 360,
                           margin: '0 auto 16px',
                        }}
                     >
                        <Space orientation="vertical" size={6} style={{ width: '100%' }}>
                           <Text style={{ fontSize: 12 }} type="secondary">
                              订单编号：<Text copyable style={{ fontSize: 12 }}>{orderId}</Text>
                           </Text>
                           <Text style={{ fontSize: 13 }}>
                              <DollarOutlined style={{ marginRight: 6, color: token.colorPrimary }} />
                              充值金额：
                              <Text strong>¥{finalAmountYuan.toLocaleString()} 元</Text>
                           </Text>
                           <Text style={{ fontSize: 13 }}>
                              <WalletOutlined style={{ marginRight: 6, color: token.colorSuccess }} />
                              到账积分：
                              <Text strong>{finalAmountYuan.toLocaleString()}</Text> 积分
                           </Text>
                        </Space>
                     </div>
                  )}

                  {/* ---- 操作按钮 ---- */}
                  <Space size={12}>
                     {isPending && payUrl && (
                        <Button
                           type="primary"
                           icon={<DollarOutlined />}
                           onClick={() => window.open(payUrl, '_blank')}
                        >
                           打开支付页面
                        </Button>
                     )}
                     {isTerminal && !isPaid && (
                        <Button type="primary" onClick={handleRetry}>
                           重新下单
                        </Button>
                     )}
                     <Button onClick={handleClose}>
                        {isPaid ? '完成' : '关闭（取消支付）'}
                     </Button>
                  </Space>
               </Result>
            </div>

            {/* ---- 协议弹窗（待支付阶段仍可查看） ---- */}
            <LegalTextModal
               open={legalOpen}
               type="points"
               onClose={() => setLegalOpen(false)}
            />
         </>
      );
   }

   // ================================================================
   // 渲染：表单视图（form 阶段）
   // ================================================================

   return (
      <>
         <div style={{ padding: '4px 0' }}>
            {/* ---- 页面副标题 ---- */}
            <Text
               type="secondary"
               style={{ fontSize: 13, marginBottom: 20, display: 'block' }}
            >
               选择充值金额或输入自定义金额（元）
            </Text>

            {/* ---- Part 1：预设金额单选组 ---- */}
            <div style={{ marginBottom: 16 }}>
               <Radio.Group
                  value={selectedAmount}
                  onChange={(e) => {
                     setSelectedAmount(e.target.value);
                     setCustomAmount(null);
                     clearError('amount');
                  }}
                  optionType="button"
                  buttonStyle="solid"
                  style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}
               >
                  {PRESET_AMOUNTS.map((amt) => (
                     <Radio.Button key={amt} value={amt}>
                        {amt} 元
                     </Radio.Button>
                  ))}
               </Radio.Group>
               {errors.amount && (
                  <Text type="danger" style={{ fontSize: 12, marginTop: 4, display: 'block' }}>
                     {errors.amount}
                  </Text>
               )}
            </div>

            {/* ---- Part 2：自定义金额输入 ---- */}
            <div style={{ marginBottom: 16 }}>
               <Space.Compact style={{ width: '100%' }}>
                  <InputNumber
                     value={customAmount}
                     onChange={(val) => {
                        setCustomAmount(val);
                        setSelectedAmount(null);
                        clearError('customAmount');
                     }}
                     min={10}
                     step={10}
                     max={MAX_AMOUNT_YUAN}
                     placeholder="输入自定义金额（10的倍数）"
                     style={{ flex: 1 }}
                     size="large"
                     precision={0}
                  />
                  <Button size="large" disabled style={{ minWidth: 44 }}>
                     元
                  </Button>
               </Space.Compact>
               {errors.customAmount && (
                  <Text type="danger" style={{ fontSize: 12, marginTop: 4, display: 'block' }}>
                     {errors.customAmount}
                  </Text>
               )}
            </div>

            {/* ---- Part 3：到账信息 + 支付金额 ---- */}
            {finalAmountYuan > 0 && (
               <div
                  style={{
                     background: isDark ? '#2E2A5A' : '#F5F3FF',
                     padding: '12px 16px',
                     borderRadius: 8,
                     marginBottom: 12,
                  }}
               >
                  <Space orientation="vertical" size={6}>
                     <Text style={{ fontSize: 13 }}>
                        <WalletOutlined style={{ marginRight: 6, color: token.colorPrimary }} />
                        到账积分：
                        <Text strong>{finalAmountYuan.toLocaleString()}</Text> 积分
                     </Text>
                     <Text style={{ fontSize: 13 }}>
                        <DollarOutlined style={{ marginRight: 6, color: token.colorSuccess }} />
                        支付金额：
                        <Text strong style={{ color: token.colorPrimary, fontSize: 15 }}>
                           ¥{finalAmountYuan.toLocaleString()}
                        </Text>
                        {' '}元
                     </Text>
                  </Space>
               </div>
            )}

            <Divider style={{ margin: '12px 0' }} />

            {/* ---- Part 4：支付方式 ---- */}
            <div style={{ marginBottom: 16 }}>
               <Text
                  type="secondary"
                  style={{ fontSize: 12, marginBottom: 8, display: 'block' }}
               >
                  选择支付方式
               </Text>
               <Radio.Group
                  value={paymentMethod}
                  onChange={(e) => handlePaymentChange(e.target.value)}
                  optionType="button"
                  buttonStyle="solid"
               >
                  <Radio.Button value={PAYMENT_METHODS.Alipay}>
                     <Space size={4}>
                        <AlipayOutlined />
                        支付宝
                     </Space>
                  </Radio.Button>
                  <Radio.Button value={PAYMENT_METHODS.WeChat}>
                     <Space size={4}>
                        <WechatOutlined />
                        微信支付
                     </Space>
                  </Radio.Button>
               </Radio.Group>
            </div>

            <Divider style={{ margin: '12px 0' }} />

            {/* ---- Part 5：充值协议 ---- */}
            <div style={{ marginBottom: 20 }}>
               <Checkbox
                  checked={agreedToTerms}
                  onChange={(e) => {
                     setAgreedToTerms(e.target.checked);
                     clearError('agreedToTerms');
                  }}
               >
                  <Text style={{ fontSize: 12 }}>
                     我已阅读并同意
                     <Button
                        type="link"
                        size="small"
                        onClick={() => setLegalOpen(true)}
                        style={{
                           padding: '0 2px',
                           fontSize: 12,
                           height: 'auto',
                           lineHeight: 'inherit',
                        }}
                     >
                        《积分充值服务协议》
                     </Button>
                  </Text>
               </Checkbox>
               {errors.agreedToTerms && (
                  <Text type="danger" style={{ fontSize: 12, marginTop: 4, display: 'block' }}>
                     {errors.agreedToTerms}
                  </Text>
               )}
            </div>

            {/* ---- Part 6：操作按钮 ---- */}
            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
               <Button onClick={handleClose}>
                  取消
               </Button>
               <Button
                  type="primary"
                  loading={submitting}
                  onClick={() => void handleSubmit()}
                  disabled={finalAmountYuan <= 0}
               >
                  提交
               </Button>
            </div>
         </div>

         {/* ---- 协议弹窗 ---- */}
         <LegalTextModal
            open={legalOpen}
            type="points"
            onClose={() => setLegalOpen(false)}
         />
      </>
   );
}
