import FormControlLabel from "@mui/material/FormControlLabel";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { useEffect, useMemo, useRef, useState } from "react";
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
import { LuckyGiftFieldLabel } from "./LuckyGiftFieldHelp.jsx";

const BASE_SECTIONS = [
    ["identity", "规则"],
    ["funds", "资金"],
];

const DYNAMIC_SECTIONS = [
    ["water", "水位"],
    ["jackpot", "大奖"],
    ["limits", "限额"],
];

export function LuckyGiftConfigSections({ appOptions, form, isCreate, onChange }) {
    const scrollRef = useRef(null);
    const sections = useMemo(
        () => (form.strategy_version === "dynamic_v3" ? [...BASE_SECTIONS, ...DYNAMIC_SECTIONS] : BASE_SECTIONS),
        [form.strategy_version],
    );
    const [activeSection, setActiveSection] = useState(sections[0][0]);

    useEffect(() => {
        if (sections.some(([sectionKey]) => sectionKey === activeSection)) return;
        // dynamic_v3 的专属分区会在切回 fixed_v2 后卸载；同步回首个有效分区，避免导航继续指向不存在的面板。
        setActiveSection(sections[0][0]);
        if (scrollRef.current) resolveConfigScroller(scrollRef.current).scrollTop = 0;
    }, [activeSection, sections]);

    useEffect(() => {
        const sectionList = scrollRef.current;
        if (!sectionList) return undefined;
        const view = sectionList.ownerDocument.defaultView;
        let boundScroller;

        const syncActiveSection = () => {
            if (!boundScroller) return;
            const readingLine =
                boundScroller.getBoundingClientRect().top + configNavInset(sectionList, boundScroller) + 32;
            let nextSection = sections[0][0];
            for (const [sectionKey] of sections) {
                const section = sectionList.querySelector(`[data-config-section="${sectionKey}"]`);
                if (section && section.getBoundingClientRect().top <= readingLine) nextSection = sectionKey;
            }
            setActiveSection((current) => (current === nextSection ? current : nextSection));
        };

        const bindActualScroller = () => {
            const nextScroller = resolveConfigScroller(sectionList);
            if (nextScroller === boundScroller) return;
            boundScroller?.removeEventListener("scroll", syncActiveSection);
            boundScroller = nextScroller;
            // 桌面由参数面板独立滚动，平板/手机由 DialogContent 单滚动；只监听真实 scroller，
            // 避免小屏内层 overflow:visible 时导航状态更新、内容位置却完全没有变化。
            boundScroller.addEventListener("scroll", syncActiveSection, { passive: true });
        };

        bindActualScroller();
        view?.addEventListener("resize", bindActualScroller);
        const ResizeObserverClass = view?.ResizeObserver;
        const resizeObserver = ResizeObserverClass ? new ResizeObserverClass(bindActualScroller) : null;
        resizeObserver?.observe(sectionList);

        return () => {
            boundScroller?.removeEventListener("scroll", syncActiveSection);
            view?.removeEventListener("resize", bindActualScroller);
            resizeObserver?.disconnect();
        };
    }, [sections]);

    const jumpToSection = (sectionKey) => {
        const sectionList = scrollRef.current;
        const section = sectionList?.querySelector(`[data-config-section="${sectionKey}"]`);
        if (!sectionList || !section) return;
        const scroller = resolveConfigScroller(sectionList);
        setActiveSection(sectionKey);
        // offsetParent 不是可靠的滚动参考系；无论当前是桌面内层还是响应式外层滚动，都用视口坐标
        // 换算同一个 scroller 的目标位点；窄屏横向导航是 sticky 覆盖层，目标还必须落到导航下方。
        const navInset = configNavInset(sectionList, scroller);
        const top = Math.max(
            scroller.scrollTop +
                section.getBoundingClientRect().top -
                scroller.getBoundingClientRect().top -
                navInset -
                8,
            0,
        );
        const reduceMotion = scroller.ownerDocument.defaultView?.matchMedia?.(
            "(prefers-reduced-motion: reduce)",
        ).matches;
        if (typeof scroller.scrollTo === "function") {
            scroller.scrollTo({ behavior: reduceMotion ? "auto" : "smooth", top });
        } else {
            // jsdom 和部分旧 WebView 没有 Element.scrollTo，直接写 scrollTop 仍能保持导航可用。
            scroller.scrollTop = top;
        }
        // 导航按钮只负责选择分区；焦点落到标题后，读屏会立即获得当前编辑上下文。
        section.querySelector("h3")?.focus({ preventScroll: true });
    };

    const fundTotal =
        Number(form.pool_rate_percent || 0) +
        Number(form.profit_rate_percent || 0) +
        Number(form.anchor_rate_percent || 0);

    return (
        <aside className="ops-config-params" aria-label="全局参数">
            <nav className="ops-config-section-nav" aria-label="全局参数分区">
                <strong>全局参数</strong>
                {sections.map(([sectionKey, label]) => (
                    <button
                        aria-controls={`ops-config-section-${sectionKey}`}
                        aria-current={activeSection === sectionKey ? "true" : undefined}
                        className={activeSection === sectionKey ? "is-active" : ""}
                        key={sectionKey}
                        type="button"
                        onClick={() => jumpToSection(sectionKey)}
                    >
                        {label}
                    </button>
                ))}
            </nav>

            <div className="ops-config-section-list" ref={scrollRef}>
                <section
                    aria-labelledby="ops-config-heading-identity"
                    className="ops-config-section"
                    data-config-section="identity"
                    id="ops-config-section-identity"
                >
                    <SectionHeading id="ops-config-heading-identity" title="规则身份" />
                    <div className="ops-form-grid">
                        {isCreate ? (
                            <TextField
                                fullWidth
                                required
                                label={<LuckyGiftFieldLabel field="app_code" label="应用" />}
                                select
                                size="small"
                                value={form.app_code}
                                onChange={(event) => onChange("app_code", event.target.value)}
                            >
                                {appOptions.map(([value, label]) => (
                                    <MenuItem key={value} value={value}>
                                        {label}
                                    </MenuItem>
                                ))}
                            </TextField>
                        ) : (
                            <TextField
                                disabled
                                fullWidth
                                label={<LuckyGiftFieldLabel field="app_code" label="应用" />}
                                size="small"
                                value={form.app_code}
                            />
                        )}
                        <TextField
                            fullWidth
                            required
                            label={<LuckyGiftFieldLabel field="pool_id" label="奖池" />}
                            size="small"
                            value={form.pool_id}
                            onChange={(event) => onChange("pool_id", event.target.value)}
                        />
                        <TextField
                            fullWidth
                            label={<LuckyGiftFieldLabel field="strategy_version" label="策略版本" />}
                            select
                            size="small"
                            value={form.strategy_version}
                            onChange={(event) => onChange("strategy_version", event.target.value)}
                        >
                            <MenuItem value="dynamic_v3">dynamic_v3</MenuItem>
                            <MenuItem value="fixed_v2">fixed_v2（历史兼容）</MenuItem>
                        </TextField>
                        <FormControlLabel
                            className="ops-config-enabled-field"
                            control={
                                <AdminSwitch
                                    checked={form.enabled}
                                    label="发布状态"
                                    onChange={(event) => onChange("enabled", event.target.checked)}
                                />
                            }
                            label={
                                <LuckyGiftFieldLabel
                                    field="enabled"
                                    label={form.enabled ? "发布后立即启用" : "发布后保持停用"}
                                />
                            }
                        />
                    </div>
                    <p className="ops-field-note">修改奖池 ID 会发布到新奖池，不影响原奖池。</p>
                </section>

                <section
                    aria-labelledby="ops-config-heading-funds"
                    className="ops-config-section"
                    data-config-section="funds"
                    id="ops-config-section-funds"
                >
                    <SectionHeading
                        detail={
                            form.strategy_version === "dynamic_v3"
                                ? `资金合计 ${formatCompactNumber(fundTotal)}%`
                                : undefined
                        }
                        id="ops-config-heading-funds"
                        ok={Math.abs(fundTotal - 100) < 0.0001}
                        title="返奖与资金分配"
                    />
                    <div className="ops-form-grid">
                        <NumberField
                            form={form}
                            label="目标 RTP (%)"
                            name="target_rtp_percent"
                            step="0.01"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="奖档允许偏差 (%)"
                            name="control_band_percent"
                            step="0.01"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="进入奖池比例 (%)"
                            name="pool_rate_percent"
                            step="0.01"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="平台收入比例 (%)"
                            name="profit_rate_percent"
                            step="0.01"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="收礼对象收益比例 (%)"
                            name="anchor_rate_percent"
                            step="0.01"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="每轮观察流水"
                            name="settlement_window_wager"
                            onChange={onChange}
                        />
                        <NumberField
                            form={form}
                            label="V2 折算参考单价"
                            name="gift_price_reference"
                            onChange={onChange}
                        />
                        <NumberField
                            disabled={form.strategy_version === "dynamic_v3"}
                            form={form}
                            label="新手阶段上限（折算次数）"
                            name="novice_max_equivalent_draws"
                            onChange={onChange}
                        />
                        <NumberField
                            disabled={form.strategy_version === "dynamic_v3"}
                            form={form}
                            label="普通阶段上限（折算次数）"
                            name="normal_max_equivalent_draws"
                            onChange={onChange}
                        />
                    </div>
                    <p className="ops-field-note">
                        发布前请核对收礼对象收益与实际送礼返币比例；不一致时，V3 真实开奖会拒绝账务结算。
                    </p>
                </section>

                {form.strategy_version === "dynamic_v3" ? (
                    <>
                        <section
                            aria-labelledby="ops-config-heading-water"
                            className="ops-config-section"
                            data-config-section="water"
                            id="ops-config-section-water"
                        >
                            <SectionHeading id="ops-config-heading-water" title="动态水位" />
                            <div className="ops-form-grid">
                                <NumberField
                                    disabled
                                    form={form}
                                    helperText="请通过奖池水位操作注资"
                                    label="初始奖池金币"
                                    name="initial_pool_coins"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="连续未中奖保护次数"
                                    name="loss_streak_guarantee"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="低水位金币"
                                    name="low_watermark_coins"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="低余额中奖权重 (%)"
                                    name="low_water_nonzero_factor_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="高水位金币"
                                    name="high_watermark_coins"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="高余额中奖权重 (%)"
                                    name="high_water_nonzero_factor_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="充值加权窗口 (ms)"
                                    name="recharge_boost_window_ms"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="充值后中奖权重 (%)"
                                    name="recharge_boost_factor_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                            </div>
                        </section>

                        <section
                            aria-labelledby="ops-config-heading-jackpot"
                            className="ops-config-section"
                            data-config-section="jackpot"
                            id="ops-config-section-jackpot"
                        >
                            <SectionHeading id="ops-config-heading-jackpot" title="大奖触发条件" />
                            <JackpotFlowSummary />
                            <div className="ops-form-grid">
                                <TextField
                                    className="ops-form-grid__wide"
                                    helperText="按从小到大填写，使用逗号分隔"
                                    label={
                                        <LuckyGiftFieldLabel field="jackpot_multipliers" label="大奖倍率（可选倍数）" />
                                    }
                                    required
                                    size="small"
                                    value={form.jackpot_multipliers}
                                    onChange={(event) => onChange("jackpot_multipliers", event.target.value)}
                                />
                                <NumberField
                                    form={form}
                                    label="全局大奖 RTP 上限 (%)"
                                    name="jackpot_global_rtp_max_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="用户本轮返还触发线 (%)"
                                    name="jackpot_user_round_rtp_max_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="用户近 48 小时返还触发线 (%)"
                                    name="jackpot_user_48h_rtp_max_percent"
                                    step="0.01"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="每位用户每日大奖次数"
                                    name="max_jackpot_hits_per_user_day"
                                    onChange={onChange}
                                />
                                <NumberField
                                    disabled
                                    form={form}
                                    helperText="仅兼容历史配置，当前规则不参与大奖资格"
                                    label="用户日累计消费触发门槛（金币）— 已停用"
                                    name="jackpot_spend_threshold_coins"
                                    onChange={onChange}
                                    required={false}
                                />
                            </div>
                        </section>

                        <section
                            aria-labelledby="ops-config-heading-limits"
                            className="ops-config-section"
                            data-config-section="limits"
                            id="ops-config-section-limits"
                        >
                            <SectionHeading id="ops-config-heading-limits" title="各场景返奖上限" />
                            <div className="ops-form-grid">
                                <NumberField
                                    form={form}
                                    label="单次返奖上限"
                                    name="max_single_payout"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="每位用户每小时最高返奖"
                                    name="user_hourly_payout_cap"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="每位用户每日最高返奖"
                                    name="user_daily_payout_cap"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="每台设备每日最高返奖"
                                    name="device_daily_payout_cap"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="每个房间每小时最高返奖"
                                    name="room_hourly_payout_cap"
                                    onChange={onChange}
                                />
                                <NumberField
                                    form={form}
                                    label="主播每日上限"
                                    name="anchor_daily_payout_cap"
                                    onChange={onChange}
                                />
                            </div>
                        </section>
                    </>
                ) : null}
            </div>
        </aside>
    );
}

function SectionHeading({ detail, id, ok = false, title }) {
    return (
        <div className="ops-config-section__head">
            <h3 id={id} tabIndex={-1}>
                {title}
            </h3>
            {detail ? <span className={ok ? "is-ok" : "is-warn"}>{detail}</span> : null}
        </div>
    );
}

function JackpotFlowSummary() {
    return (
        <div className="ops-jackpot-flow" aria-label="大奖产生方式">
            <div>
                <strong>1. 大盘先通过</strong>
                <span>本轮大盘 RTP 不高于全局触发线，才继续检查用户；等于触发线也可通过。</span>
            </div>
            <div>
                <strong>2. 用户两项都通过</strong>
                <span>用户本轮 RTP 和近 48 小时 RTP 都必须严格低于各自触发线，少一项都不能出大奖。</span>
            </div>
            <div>
                <strong>3. 下次送礼尝试大奖</strong>
                <span>
                    用户下次送礼时，先剔除奖池或限额付不起的倍率，再随机选择；没有可支付倍率就不出大奖，本轮资格也不会顺延或重复使用。
                </span>
            </div>
        </div>
    );
}

function NumberField({ disabled = false, form, helperText, label, name, onChange, required = true, step = "1" }) {
    return (
        <TextField
            disabled={disabled}
            helperText={helperText}
            label={<LuckyGiftFieldLabel field={name} label={label} />}
            required={required}
            size="small"
            slotProps={{ htmlInput: { inputMode: "decimal", min: 0, step } }}
            type="number"
            value={form[name]}
            onChange={(event) => onChange(name, event.target.value)}
        />
    );
}

function formatCompactNumber(value) {
    return Number.isFinite(value) ? Number(value.toFixed(4)).toString() : "-";
}

function resolveConfigScroller(sectionList) {
    // 桌面参数列限定高度后由自己滚动；响应式规则把它改为 overflow:visible，此时 scrollHeight 与
    // clientHeight 相等，实际滚动责任上移到 DialogContent。判定能力而非 viewport 宽度可兼容缩放和嵌入场景。
    if (sectionList.scrollHeight > sectionList.clientHeight) return sectionList;
    return sectionList.closest(".ops-config-dialog-content") || sectionList;
}

function configNavInset(sectionList, scroller) {
    if (scroller === sectionList) return 0;
    const nav = sectionList.previousElementSibling;
    if (!nav?.classList.contains("ops-config-section-nav")) return 0;
    // 响应式是否形成覆盖层由真实布局决定：390px 时 nav 为横向 row，1024px 时仍是左侧 column。
    // 读取 computed style 而不是猜 innerWidth，才能兼容浏览器缩放、嵌入容器和未来断点调整。
    const flexDirection = nav.ownerDocument.defaultView?.getComputedStyle(nav).flexDirection;
    return flexDirection === "row" ? nav.getBoundingClientRect().height : 0;
}
