// ============================================================
// VipPage — VIP 会员开通页面
//
// 通过 PageDispatcher 调度（Modal 容器），导航栏"开会员/激活"按钮触发。
// 四部分布局：
//   激活码    — Space.Compact 输入框 + 激活按钮
//   套餐选择  — Radio.Group 卡片式单选，API 获取套餐列表
//   支付协议  — Checkbox + LegalTextModal（用户服务协议） + 确认开通
//   权益说明  — 选中套餐的大图展示
// ============================================================

import {useState, useCallback, useEffect, useRef} from 'react';
import { logger } from '@/shared/utils/bus';
import {
    Radio,
    Button,
    Checkbox,
    Input,
    Image,
    Typography,
    App,
    Space,
    Divider,
    theme as antTheme,
    Spin,
    Result,
} from 'antd';
import {CrownOutlined, GiftOutlined, DollarOutlined} from '@ant-design/icons';

import {useTheme} from '@/app/providers/ThemeProvider';
import {LegalTextModal} from '@/shared/components/LegalTextModal';
import {
    VipAPI,
    VipOrderStatus,
    type VipLevelsItem,
    type VipOrderStatusValue,
} from '@/modules/account/controllers/vip-api';
import {centToYuan} from '@/shared/utils/display';
import {EnumResolver} from '@/shared/utils/enum-resolver';
import {emit, EVENTS} from '@/shared/utils/bus';
import {RequestError, RequestErrorType} from '@/shared/services/http';

const {Text} = Typography;

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

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

/** 页面阶段 */
type VipPhase = 'form' | 'activate' | VipOrderStatusValue;

/** 状态 → Result status 映射 */
function getResultStatus(status: VipOrderStatusValue): 'success' | 'info' | 'error' {
    if (status === VipOrderStatus.Paid) return 'success';
    if (status === VipOrderStatus.Pending) return 'info';
    return 'error';
}

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

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

    // ======== 套餐列表 ========

    const [levels, setLevels] = useState<VipLevelsItem[]>([]);
    const [loading, setLoading] = useState(true);
    const [fetchError, setFetchError] = useState<string | null>(null);
    const abortRef = useRef<AbortController | null>(null);
    const mountedRef = useRef(true);

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

    const [selectedLevelId, setSelectedLevelId] = useState<number | null>(null);
    const [agreedToTerms, setAgreedToTerms] = useState(false);
    const [submitting, setSubmitting] = useState(false);
    const [errors, setErrors] = useState<Record<string, string>>({});
    const [legalOpen, setLegalOpen] = useState(false);

    // ======== 激活码 ========

    const [activateCode, setActivateCode] = useState('');
    const [activating, setActivating] = useState(false);

    // ======== 支付订单状态 ========

    const [phase, setPhase] = useState<VipPhase>('form');
    const [vipOrderId, setVipOrderId] = useState<string | null>(null);
    const [vipOrderStatus, setVipOrderStatus] = useState<VipOrderStatusValue | null>(null);
    const [vipPayUrl, setVipPayUrl] = useState<string | null>(null);

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

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

    // ======== 获取套餐列表 ========

    const fetchLevels = useCallback(async () => {
        abortRef.current?.abort();
        const controller = new AbortController();
        abortRef.current = controller;

        setLoading(true);
        setFetchError(null);
        try {
            const data = await VipAPI.getVipLevels(controller.signal);
            if (mountedRef.current) {
                setLevels(data.filter((l) => l.is_active && l.image));
            }
        } catch (err) {
            // axios 拦截器将取消错误转为 RequestError(CANCELLED)，非原始 AbortError
            if (err instanceof RequestError && err.type === RequestErrorType.CANCELLED) return;
            logger.warn('ui', '加载VIP套餐列表失败', err instanceof Error ? err : new Error(String(err)));
            if (mountedRef.current) {
                setFetchError((err as Error)?.message || '加载套餐列表失败');
            }
        } finally {
            if (mountedRef.current) {
                setLoading(false);
            }
        }
    }, []);

    useEffect(() => {
        mountedRef.current = true;
        void fetchLevels();
        return () => {
            mountedRef.current = false;
            abortRef.current?.abort();
        };
    }, [fetchLevels]);

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

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

        if (selectedLevelId === null) {
            errs.selectedLevel = '请选择会员套餐';
        }

        if (!agreedToTerms) {
            errs.agreedToTerms = '请阅读并同意用户服务协议';
        }

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

    // ======== 提交 ========

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

        setSubmitting(true);
        try {
            const res = await VipAPI.createVipOrder({
                vip_level_id: selectedLevelId!,
                payment_channel: 'alipay',
            });

            // 保存订单信息，进入待支付阶段
            setVipOrderId(res.id);
            setVipOrderStatus(VipOrderStatus.Pending);
            setVipPayUrl(res.pay_url);
            setPhase(VipOrderStatus.Pending);

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

    // ======== 激活码提交 ========

    const handleActivate = useCallback(async () => {
        const code = activateCode.trim();
        if (!code) {
            message.warning('请输入激活码');
            return;
        }

        setActivating(true);
        try {
            await VipAPI.activateVipCode({code});
            void message.success('激活成功！VIP 权益已生效');
            emit(EVENTS.CLOSE_PAGE);
        } catch (err: unknown) {
            logger.warn('ui', 'VIP激活失败', err instanceof Error ? err : new Error(String(err)));
            message.error((err as Error)?.message || '激活失败，请检查激活码是否正确');
        } finally {
            setActivating(false);
        }
    }, [activateCode, message]);

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

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

    useEffect(() => {
        if (phase !== VipOrderStatus.Pending || !vipOrderId) return;

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

        const poll = async () => {
            try {
                const order = await VipAPI.getVipOrder(vipOrderId);
                if (cancelled) return;

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

                if (newStatus === VipOrderStatus.Pending) {
                    timer = setTimeout(poll, POLL_INTERVAL_MS);
                } else {
                    setPhase(newStatus);
                    if (newStatus === VipOrderStatus.Paid) {
                        void message.success('支付成功！VIP 权益已生效');
                    }
                }
            } catch {
                if (!cancelled) timer = setTimeout(poll, POLL_INTERVAL_MS * 2);
            }
        };

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

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

    useEffect(() => {
        const locked = phase === VipOrderStatus.Pending;
        emit(EVENTS.PAGE_LOCK, { locked });
        return () => {
            if (locked) emit(EVENTS.PAGE_LOCK, { locked: false });
        };
    }, [phase]);

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

    /** 重新下单：回到表单，保留套餐选择 */
    const handleRetry = useCallback(() => {
        setPhase('form');
        setVipOrderId(null);
        setVipOrderStatus(null);
        setVipPayUrl(null);
    }, []);

    const handleClose = useCallback(() => {
        emit(EVENTS.CLOSE_PAGE);
    }, []);

    // ================================================================
    // 渲染：加载态
    // ================================================================

    if (loading) {
        return (
            <div style={{display: 'flex', justifyContent: 'center', padding: '48px 0'}}>
                <Spin size="medium">
                    <div style={{padding: 24, textAlign: 'center'}}>
                        <Text type="secondary" style={{fontSize: 13}}>加载套餐列表…</Text>
                    </div>
                </Spin>
            </div>
        );
    }

    // ================================================================
    // 渲染：错误态
    // ================================================================

    if (fetchError) {
        return (
            <div style={{padding: '8px 0'}}>
                <Result
                    status="error"
                    title="套餐加载失败"
                    subTitle={fetchError}
                    extra={
                        <Button type="primary" size="small" onClick={fetchLevels}>
                            重试
                        </Button>
                    }
                />
            </div>
        );
    }

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

    if (phase !== 'form' && phase !== 'activate') {
        const statusText = vipOrderStatus ? EnumResolver.vip.orderStatus.label(vipOrderStatus) : '';
        const isPending = phase === VipOrderStatus.Pending;
        const isPaid = phase === VipOrderStatus.Paid;

        return (
            <>
                <div style={{ padding: '16px 0' }}>
                    <Result
                        status={vipOrderStatus ? getResultStatus(vipOrderStatus) : 'info'}
                        title={
                            isPaid
                                ? '支付成功'
                                : isPending
                                    ? `等待支付（${statusText}）`
                                    : statusText
                        }
                        subTitle={
                            isPaid
                                ? 'VIP 会员权益已生效'
                                : 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 }}>{vipOrderId}</Text>
                                    </Text>
                                    <Text style={{ fontSize: 13 }}>
                                        <DollarOutlined style={{ marginRight: 6, color: token.colorPrimary }} />
                                        支付金额：
                                        <Text strong>
                                            ¥{(() => {
                                                const lvl = levels.find((l) => l.id === selectedLevelId);
                                                return lvl ? centToYuan(lvl.price_cent) : '—';
                                            })()}
                                        </Text>
                                    </Text>
                                    <Text style={{ fontSize: 13 }}>
                                        <CrownOutlined style={{ marginRight: 6, color: token.colorSuccess }} />
                                        套餐：
                                        <Text strong>{levels.find((l) => l.id === selectedLevelId)?.name ?? '—'}</Text>
                                    </Text>
                                </Space>
                            </div>
                        )}

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

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

    // ================================================================
    // 渲染：正常
    // ================================================================

    return (
        <>
            <div style={{padding: '4px 0'}}>
                <div>
                    <Text type="secondary" style={{fontSize: 13, marginBottom: 10, display: 'block'}}>
                        <GiftOutlined style={{marginRight: 4}} />
                        使用激活码
                    </Text>
                    <Space.Compact style={{width: '100%'}}>
                        <Input
                            value={activateCode}
                            onChange={(e) => setActivateCode(e.target.value)}
                            placeholder="输入 VIP 激活码"
                            allowClear
                            onPressEnter={() => void handleActivate()}
                            style={{flex: 1}}
                        />
                        <Button
                            type="primary"
                            icon={<GiftOutlined />}
                            loading={activating}
                            onClick={() => void handleActivate()}
                            disabled={!activateCode.trim()}
                        >
                            激活
                        </Button>
                    </Space.Compact>
                </div>
                <Divider style={{margin: '20px 0 16px'}} />
                <Text type="secondary" style={{fontSize: 13, marginBottom: 12, display: 'block'}}>
                    选择会员套餐
                </Text>

                {/* 双列布局：左列套餐选择 | 右列权益图库 */}
                <div style={{display: 'flex', gap: 12, marginBottom: 16}}>
                    {/* ---- 左列：套餐选择 ---- */}
                    <div style={{flex: '0 0 52%', minWidth: 0}}>
                        <Radio.Group
                            value={selectedLevelId}
                            onChange={(e) => {
                                setSelectedLevelId(e.target.value);
                                clearError('selectedLevel');
                            }}
                            style={{width: '100%'}}
                        >
                            <Space orientation="vertical" style={{width: '100%'}} size={6}>
                                {levels.map((level) => (
                                    <Radio
                                        key={level.id}
                                        value={level.id}
                                        style={{
                                            display: 'flex',
                                            alignItems: 'flex-start',
                                            padding: '10px 12px',
                                            borderRadius: 8,
                                            border: `1px solid ${
                                                selectedLevelId === level.id
                                                    ? token.colorPrimary
                                                    : isDark
                                                        ? '#2E2A5A'
                                                        : '#E5E7EB'
                                            }`,
                                            background:
                                                selectedLevelId === level.id
                                                    ? isDark
                                                        ? '#2E2A5A'
                                                        : '#F5F3FF'
                                                    : isDark
                                                        ? '#1A1730'
                                                        : '#FFFFFF',
                                            width: '100%',
                                            margin: 0,
                                            transition: 'border-color 0.2s, background 0.2s',
                                        }}
                                    >
                                        <div style={{flex: 1, marginLeft: 8, minWidth: 0}}>
                                            <div
                                                style={{
                                                    display: 'flex',
                                                    justifyContent: 'space-between',
                                                    alignItems: 'baseline',
                                                    marginBottom: 4,
                                                }}
                                            >
                                                <Text strong style={{fontSize: 13}}>
                                                    {level.name}
                                                </Text>
                                                <Text
                                                    strong
                                                    style={{
                                                        fontSize: 14,
                                                        color: token.colorPrimary,
                                                        whiteSpace: 'nowrap',
                                                    }}
                                                >
                                                    ¥{centToYuan(level.price_cent)}
                                                </Text>
                                            </div>
                                            <div style={{display: 'flex', gap: 8, flexWrap: 'wrap'}}>
                                                <Text type="secondary" style={{fontSize: 11}}>
                                                    {level.duration_days}天
                                                </Text>
                                                {level.gift_balance_cent > 0 && (
                                                    <Text type="secondary" style={{fontSize: 11}}>
                                                        赠{centToYuan(level.gift_balance_cent)}积分
                                                    </Text>
                                                )}
                                                <Text type="secondary" style={{fontSize: 11}}>
                                                    {EnumResolver.vip.targetAccountType.label(level.target_account_type)}
                                                </Text>
                                            </div>
                                            {level.description && (
                                                <Text type="secondary" style={{fontSize: 10, display: 'block', marginTop: 2}}>
                                                    {level.description}
                                                </Text>
                                            )}
                                        </div>
                                    </Radio>
                                ))}
                            </Space>
                        </Radio.Group>

                        {errors.selectedLevel && (
                            <Text type="danger" style={{fontSize: 12, marginTop: 4, display: 'block'}}>
                                {errors.selectedLevel}
                            </Text>
                        )}
                    </div>

                    {/* ---- 右列：权益图库 ---- */}
                    <div
                        style={{
                            flex: 1,
                            minWidth: 0,
                            display: 'flex',
                            flexDirection: 'column',
                            gap: 6,
                        }}
                    >
                        <Text type="secondary" style={{fontSize: 11, textAlign: 'center'}}>
                            权益说明（点击放大）
                        </Text>
                        {levels.map((level) => (
                            <div
                                key={level.id}
                                style={{
                                    borderRadius: 6,
                                    overflow: 'hidden',
                                    border: `2px solid ${
                                        selectedLevelId === level.id
                                            ? token.colorPrimary
                                            : 'transparent'
                                    }`,
                                    opacity: selectedLevelId === null || selectedLevelId === level.id ? 1 : 0.45,
                                    transition: 'border-color 0.2s, opacity 0.2s',
                                    cursor: 'pointer',
                                }}
                            >
                                <Image
                                    src={level.image!}
                                    alt={`${level.name} 权益`}
                                    width="100%"
                                    style={{display: 'block'}}
                                    preview={{mask: '查看大图'}}
                                />
                            </div>
                        ))}
                    </div>
                </div>

                {/* ---- Part 2：支付协议 + 确认开通 ---- */}
                <div style={{marginBottom: 16}}>
                    <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>

                {/* 操作按钮 */}
                <div style={{display: 'flex', justifyContent: 'flex-end', gap: 8}}>
                    <Button onClick={handleClose}>取消</Button>
                    <Button
                        type="primary"
                        icon={<CrownOutlined />}
                        loading={submitting}
                        onClick={() => void handleSubmit()}
                        disabled={selectedLevelId === null}
                    >
                        确认开通
                    </Button>
                </div>
            </div>

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