// ============================================================
// PageDispatcher — 页面事件调度器
//
// 监听 EVENTS.OPEN_PAGE，根据 modalType 渲染对应容器：
//   - modal    → antd Modal（居中模态，有遮罩阻断交互）
//   - drawer   → antd Drawer（侧滑抽屉）
//   - floating → FloatingPanel（非模态浮动面板，可拖拽，不阻断交互）
//
// 全局互斥：同一时刻最多打开一个页面组件。
// 已打开时不响应 OPEN_PAGE 事件（保留面板内互操作能力：拖拽、图片拖放等）。
//
// PAGE_MAP 集中注册所有可调度页面：
//   有真实组件 → { component: XxxPage, label: '...', width?: number }
//   占位页面   → 只写 label，自动渲染 "页面开发中"
//   懒加载页面 → component: React.lazy(() => import('...'))
//   新增页面只需在这里加一行，无需创建独立文件
// ============================================================

import {type ComponentType, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {Drawer, Modal} from 'antd';
import {EVENTS, off, on} from '@/shared/utils/bus';
import {FloatingPanel} from '@/shared/components/FloatingPanel';

import {WechatWorkPage} from '@/modules/account/views/wechat-work/WechatWorkPage';
import {AccountInfo} from '@/modules/account/views/info/AccountPage';
import {BillingInfo} from '@/modules/account/views/billing/BillingPage';
import {RechargePage} from '@/modules/account/views/recharge/RechargePage';
import {OrdersPage} from '@/modules/account/views/orders/OrdersPage';
import {VipPage} from '@/modules/account/views/vip/VipPage';

// ---------- 类型 ----------

type ModalType = 'modal' | 'drawer' | 'floating';

interface PageEventPayload {
    target: string;
    modalType: ModalType;
    label: string;
}

/** 当前活跃面板（id 用于 key / 关闭定位） */
interface ActivePanel extends PageEventPayload {
    id: string;
}

interface PageConfig {
    /** 页面组件（未提供则使用自动生成的占位组件）。
     *  支持 React.lazy(() => import('...')) 懒加载。 */
    component?: ComponentType;
    /** 页面标签（显示在容器标题栏） */
    label: string;
    /** 容器宽度（px）。也支持函数动态计算：() => window.innerWidth * 0.6 */
    width?: number | (() => number);
    /** 容器高度（px），仅 FloatingPanel 生效。也支持函数动态计算 */
    height?: number | (() => number);
}

// ---------- 占位组件（模块级，引用稳定，避免渲染中创建组件） ----------

function PlaceholderPage({label}: { label: string }) {
    return (
        <div style={{padding: 8}}>
            <p style={{color: 'inherit', opacity: 0.6, margin: 0}}>{label} — 页面开发中</p>
        </div>
    );
}

/** 为每个占位页预创建稳定组件引用 */
function createPlaceholder(label: string): ComponentType {
    const C = () => <PlaceholderPage label={label} />;
    C.displayName = `Placeholder_${label}`;
    return C;
}

// ---------- target → 页面组件映射 ----------

const PAGE_MAP: Record<string, PageConfig> = {
    '/wechat-work': {component: WechatWorkPage, label: '企业微信'},
    '/compliance-assets': {label: '合规素材库'},
    '/account': {
        component: AccountInfo,
        label: '账户',
        width: () => Math.min(window.outerHeight * 0.65, 720),
        height: () => Math.min(window.outerHeight * 0.65, 680),
    },
    '/vip': {component: VipPage, label: 'VIP 会员开通', width: 560},
    '/recharge': {component: RechargePage, label: '充值', width: 520},
    '/billing': {label: '账单记录',
        component: BillingInfo,
        width: 960,
        height: 680,},
    '/orders': {
        component: OrdersPage,
        label: '订单明细',
        width: 820,
        height: 640,
    },
    '/projects': {label: '项目管理'},
    '/quota': {
        component: AccountInfo,
        label: '配额',
        width: () => Math.min(window.outerHeight * 0.65, 720),
        height: () => Math.min(window.outerHeight * 0.65, 680),
    },
};

// 预计算所有占位组件（模块加载时执行一次，引用永久稳定）
const RESOLVED_PAGE_MAP = new Map<string, ComponentType>();
for (const [key, config] of Object.entries(PAGE_MAP)) {
    RESOLVED_PAGE_MAP.set(key, config.component || createPlaceholder(config.label));
}

/** 解析页面组件（纯查表，不创建新组件） */
function resolvePage(target: string): ComponentType | null {
    return RESOLVED_PAGE_MAP.get(target) || null;
}

/** 解析容器宽度（支持静态数值或动态函数） */
function resolveWidth(target: string): number | undefined {
    const w = PAGE_MAP[target]?.width;
    return typeof w === 'function' ? w() : w;
}

/** 解析容器高度（支持静态数值或动态函数） */
function resolveHeight(target: string): number | undefined {
    const h = PAGE_MAP[target]?.height;
    return typeof h === 'function' ? h() : h;
}

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

export function PageDispatcher() {
    const [activePanel, setActivePanel] = useState<ActivePanel | null>(null);
    const nextIdRef = useRef(0);
    const [locked, setLocked] = useState(false);

    // 关闭面板
    const closePanel = useCallback(() => {
        setActivePanel(null);
    }, []);

    // 监听 OPEN_PAGE 事件
    useEffect(() => {
        const handler = (payload: unknown) => {
            const {target, modalType, label} = payload as PageEventPayload;

            if (!target || !PAGE_MAP[target]) {
                console.warn(`[PageDispatcher] 未找到页面组件: ${target}`);
                return;
            }

            // 全局互斥：已有面板打开时，禁止打开新面板
            // 不关闭已有面板，保留其内部互操作能力（拖拽、图片拖放等）
            setActivePanel((prev) => {
                if (prev) return prev;
                return {id: `pnl-${nextIdRef.current++}`, target, modalType, label};
            });
        };

        on(EVENTS.OPEN_PAGE, handler);
        return () => off(EVENTS.OPEN_PAGE, handler);
    }, []);

    // 监听 CLOSE_PAGE 事件（允许页面组件内部"取消"按钮关闭容器）
    useEffect(() => {
        on(EVENTS.CLOSE_PAGE, closePanel);
        return () => off(EVENTS.CLOSE_PAGE, closePanel);
    }, [closePanel]);

    // 监听 PAGE_LOCK 事件（页面组件操作进行中时禁止关闭容器）
    useEffect(() => {
        const handler = (payload: unknown) => {
            setLocked((payload as { locked: boolean }).locked);
        };
        on(EVENTS.PAGE_LOCK, handler);
        return () => off(EVENTS.PAGE_LOCK, handler);
    }, []);

    // 面板关闭时重置锁定状态（防止下次打开时仍处于锁定）
    useEffect(() => {
        if (!activePanel) setLocked(false);
    }, [activePanel]);

    // 页面组件（useMemo 稳定引用）
    const PanelPage = useMemo<ComponentType | null>(
        () => (activePanel ? resolvePage(activePanel.target) : null),
        [activePanel],
    );

    const panelWidth = activePanel ? resolveWidth(activePanel.target) : undefined;
    const panelHeight = activePanel ? resolveHeight(activePanel.target) : undefined;

    // 容器默认尺寸（动态计算，视口缩放自动适配）
    const defaultModalWidth = Math.min(window.innerWidth * 0.55, 720);
    const defaultDrawerWidth = Math.min(window.innerWidth * 0.38, 520);

    return (
        <>
            {/* ======== Modal ======== */}
            {activePanel?.modalType === 'modal' && PanelPage && (
                <Modal
                    open
                    centered
                    title={activePanel.label}
                    onCancel={closePanel}
                    footer={null}
                    destroyOnHidden={true}
                    mask={{closable: !locked}}
                    width={panelWidth ?? defaultModalWidth}
                >
                    {/* eslint-disable-next-line react-hooks/static-components */}
                    <PanelPage />
                </Modal>
            )}

            {/* ======== Drawer ======== */}
            {activePanel?.modalType === 'drawer' && PanelPage && (
                <Drawer
                    open
                    title={activePanel.label}
                    onClose={closePanel}
                    destroyOnHidden={true}
                    mask={{
                        closable:locked
                    }}
                    size={panelWidth ?? defaultDrawerWidth}
                >
                    {/* eslint-disable-next-line react-hooks/static-components */}
                    <PanelPage />
                </Drawer>
            )}

            {/* ======== Floating Panel ======== */}
            {activePanel?.modalType === 'floating' && PanelPage && (
                <FloatingPanel
                    key={activePanel.id}
                    open
                    title={activePanel.label}
                    onClose={closePanel}
                    width={panelWidth ?? defaultDrawerWidth}
                    height={panelHeight}
                >
                    {/* eslint-disable-next-line react-hooks/static-components */}
                    <PanelPage />
                </FloatingPanel>
            )}
        </>
    );
}
