import CloseOutlined from "@mui/icons-material/CloseOutlined";
import EditOutlined from "@mui/icons-material/EditOutlined";
import HelpOutlineOutlined from "@mui/icons-material/HelpOutlineOutlined";
import RefreshOutlined from "@mui/icons-material/RefreshOutlined";
import SaveOutlined from "@mui/icons-material/SaveOutlined";
import SettingsOutlined from "@mui/icons-material/SettingsOutlined";
import Checkbox from "@mui/material/Checkbox";
import CircularProgress from "@mui/material/CircularProgress";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogTitle from "@mui/material/DialogTitle";
import FormControlLabel from "@mui/material/FormControlLabel";
import IconButton from "@mui/material/IconButton";
import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField";
import { useMemo, useState } from "react";
import { ResourceSelectField } from "@/features/resources/components/ResourceSelectDrawer.jsx";
import {
    vipBenefitResourceTypes,
    vipGrantModeLabels,
    vipProgramDefaults,
    vipProgramLabels,
    vipProgramOptions,
    vipUpgradePolicyLabels,
} from "@/features/vip-config/constants.js";
import { useVipConfigPage } from "@/features/vip-config/hooks/useVipConfigPage.js";
import {
    readVipBenefitMetadata,
    updateVipBenefitMetadataField,
    vipBenefitMetadataField,
} from "@/features/vip-config/metadata.js";
import styles from "@/features/vip-config/vip-config.module.css";
import { AdminListPage } from "@/shared/ui/AdminListLayout.jsx";
import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx";
import { Button } from "@/shared/ui/Button.jsx";
import { DataState } from "@/shared/ui/DataState.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { ResourceGroupSelectField } from "@/shared/ui/ResourceGroupSelectDrawer.jsx";
import { formatMillis } from "@/shared/utils/time.js";

const benefitFilterOptions = [
    ["all", "全部"],
    ["active", "已启用"],
    ["disabled", "未启用"],
    ["decoration", "装扮"],
    ["function", "功能"],
];

const benefitGroupDefinitions = [
    ["decoration", "装扮资源"],
    ["user", "身份与资料"],
    ["room", "房间与互动"],
    ["wallet", "钱包返利"],
    ["notice", "通知能力"],
];

const emptyBenefitList = [];

export function VipConfigPage() {
    const page = useVipConfigPage();
    const levels = page.config.levels || [];
    const columns = useMemo(() => vipColumns(), []);
    const programDefaults = vipProgramDefaults[page.program.programType];
    const editing = Boolean(page.editorMode);

    return (
        <AdminListPage>
            <div className={styles.pageScroll}>
                <section className={styles.overviewSection}>
                    <div className={styles.sectionHeader}>
                        <div className={styles.sectionTitleGroup}>
                            <h2 className={styles.pageTitle}>VIP配置</h2>
                            <span className={styles.pageSubtitle}>
                                {page.appCode || "-"} · {vipProgramLabels[page.program.programType] || "VIP"}
                            </span>
                        </div>
                        <div className={styles.headerActions}>
                            <Button
                                disabled={page.loading || editing}
                                startIcon={<RefreshOutlined fontSize="small" />}
                                onClick={page.reload}
                            >
                                刷新
                            </Button>
                            {page.abilities.canUpdate ? (
                                <Button
                                    disabled={page.loading || editing}
                                    startIcon={<SettingsOutlined fontSize="small" />}
                                    onClick={page.openProgramEditor}
                                >
                                    体系设置
                                </Button>
                            ) : null}
                            {page.abilities.canUpdate ? (
                                <Button
                                    disabled={page.loading || editing || !levels.length}
                                    startIcon={<EditOutlined fontSize="small" />}
                                    variant="primary"
                                    onClick={page.openLevelsEditor}
                                >
                                    编辑配置
                                </Button>
                            ) : null}
                        </div>
                    </div>

                    <div className={styles.summaryItems}>
                        <SummaryItem label="体系状态">
                            {page.program.status === "disabled" ? "停用" : "启用"}
                        </SummaryItem>
                        <SummaryItem label="等级数量">{levels.length || page.program.levelCount}</SummaryItem>
                        <SummaryItem label="启用等级">{page.activeCount}</SummaryItem>
                        <SummaryItem label="高等级升级">
                            {vipUpgradePolicyLabels[
                                page.program.upgradeExpiryPolicy || programDefaults.upgradeExpiryPolicy
                            ] || "-"}
                        </SummaryItem>
                        <SummaryItem label="后台发放">
                            {vipGrantModeLabels[page.program.grantMode || programDefaults.grantMode] || "-"}
                        </SummaryItem>
                    </div>

                    <DataState error={page.error} loading={page.loading} onRetry={page.reload}>
                        <DataTable
                            className={styles.overviewTable}
                            columns={columns}
                            items={levels}
                            minWidth="720px"
                            resizableColumns={false}
                            rowKey={(item) => item.level}
                        />
                    </DataState>
                </section>
            </div>
            {page.editorMode === "program" ? <VipProgramDialog page={page} /> : null}
            {page.editorMode === "levels" ? <VipLevelsDialog page={page} /> : null}
        </AdminListPage>
    );
}

function VipProgramDialog({ page }) {
    const disabled = !page.abilities.canUpdate || page.saving || page.loading;
    const defaults = vipProgramDefaults[page.programForm.programType];
    return (
        <Dialog
            aria-labelledby="vip-program-dialog-title"
            fullWidth
            maxWidth="md"
            open
            slotProps={{ paper: { className: styles.programDialogPaper } }}
            onClose={page.saving ? undefined : page.closeEditor}
        >
            <form className={styles.programDialogForm} onSubmit={page.submitProgram}>
                <DialogTitle className={styles.dialogTitle} component="div">
                    <div>
                        <h2 id="vip-program-dialog-title">VIP体系设置</h2>
                        <span>体系决定等级数量、升级计时和后台发放方式</span>
                    </div>
                    <IconButton aria-label="关闭VIP体系设置" disabled={page.saving} onClick={page.closeEditor}>
                        <CloseOutlined fontSize="small" />
                    </IconButton>
                </DialogTitle>
                <DialogContent className={styles.programDialogContent}>
                    <div className={styles.programGrid}>
                        <TextField
                            disabled={disabled}
                            label="体系"
                            required
                            select
                            size="small"
                            value={page.programForm.programType}
                            onChange={(event) => page.updateProgramField({ programType: event.target.value })}
                        >
                            {vipProgramOptions.map(([value, label]) => (
                                <MenuItem key={value} value={value}>
                                    {label}
                                </MenuItem>
                            ))}
                        </TextField>
                        <TextField disabled label="等级数量" size="small" value={page.programForm.levelCount} />
                        <TextField
                            disabled
                            label="高等级升级"
                            size="small"
                            value={vipUpgradePolicyLabels[defaults.upgradeExpiryPolicy]}
                        />
                        <TextField
                            disabled
                            label="后台发放"
                            size="small"
                            value={vipGrantModeLabels[defaults.grantMode]}
                        />
                        <SwitchField
                            checked={page.programForm.enabled}
                            disabled={disabled}
                            label="体系状态"
                            onChange={(event) => page.updateProgramField({ enabled: event.target.checked })}
                        />
                    </div>
                    <div className={styles.inlineNotice}>
                        体系与等级配置分别保存。切换体系后，请重新打开“编辑配置”维护对应的 9/10 个等级。
                    </div>
                </DialogContent>
                <DialogActions className={styles.dialogActions}>
                    <Button disabled={page.saving} type="button" onClick={page.closeEditor}>
                        取消
                    </Button>
                    <Button
                        disabled={disabled}
                        startIcon={
                            page.saving ? (
                                <CircularProgress color="inherit" size={16} />
                            ) : (
                                <SaveOutlined fontSize="small" />
                            )
                        }
                        type="submit"
                        variant="primary"
                    >
                        保存体系
                    </Button>
                </DialogActions>
            </form>
        </Dialog>
    );
}

function VipLevelsDialog({ page }) {
    const levels = page.form.levels || [];
    // 等级、筛选与当前权益只属于弹窗浏览状态；完整草稿仍由 Hook 持有，切换等级不会截断整包提交。
    const [selectedLevelNumber, setSelectedLevelNumber] = useState(levels[0]?.level || 1);
    const activeLevel = levels.find((level) => level.level === selectedLevelNumber) || levels[0];
    const [benefitQuery, setBenefitQuery] = useState("");
    const [benefitFilter, setBenefitFilter] = useState("all");
    const [selectedBenefitCode, setSelectedBenefitCode] = useState(activeLevel?.benefits?.[0]?.benefitCode || "");
    const [showRules, setShowRules] = useState(false);
    const disabled = !page.abilities.canUpdate || page.saving || page.loading;
    const isP1 = page.program.programType === "tiered_privilege_v1";
    const benefits = activeLevel?.benefits || emptyBenefitList;
    const activeBenefitCount = benefits.filter((benefit) => benefit.status === "active").length;
    const selectedBenefit = benefits.find((benefit) => benefit.benefitCode === selectedBenefitCode) || benefits[0];
    const filteredGroups = useMemo(
        () => groupVisibleBenefits(benefits, benefitQuery, benefitFilter),
        [benefitFilter, benefitQuery, benefits],
    );

    function selectLevel(level) {
        setSelectedLevelNumber(level.level);
        setSelectedBenefitCode(level.benefits?.[0]?.benefitCode || "");
        setBenefitQuery("");
        setBenefitFilter("all");
        setShowRules(false);
    }

    function selectBenefit(benefitCode) {
        setSelectedBenefitCode(benefitCode);
        setShowRules(false);
    }

    if (!activeLevel) return null;

    return (
        <Dialog
            aria-labelledby="vip-levels-dialog-title"
            className={styles.levelsDialog}
            maxWidth={false}
            open
            slotProps={{ paper: { className: styles.levelsDialogPaper } }}
            onClose={page.saving ? undefined : page.closeEditor}
        >
            <form className={styles.levelsDialogForm} onSubmit={page.submitLevels}>
                <DialogTitle className={styles.levelsDialogTitle} component="div">
                    <div className={styles.dialogHeading}>
                        <h2 id="vip-levels-dialog-title">VIP等级配置</h2>
                        <span>
                            {page.appCode || "当前 App"} · {vipProgramLabels[page.program.programType] || "VIP"}
                        </span>
                    </div>
                    <div className={styles.dialogHeaderActions}>
                        <span className={styles.dialogStat}>{levels.length} 个等级</span>
                        <span className={styles.dialogStat}>
                            {levels.filter((level) => level.status === "active").length} 个启用
                        </span>
                        <Button
                            aria-pressed={showRules}
                            className={styles.rulesButton}
                            startIcon={<HelpOutlineOutlined fontSize="small" />}
                            type="button"
                            onClick={() => setShowRules((current) => !current)}
                        >
                            规则说明
                        </Button>
                        <IconButton aria-label="关闭VIP等级配置" disabled={page.saving} onClick={page.closeEditor}>
                            <CloseOutlined fontSize="small" />
                        </IconButton>
                    </div>
                </DialogTitle>

                <DialogContent className={styles.levelsDialogContent}>
                    <nav aria-label="VIP等级" className={styles.levelRail}>
                        <div className={styles.levelRailHeading}>
                            <strong>等级</strong>
                            <span>选择后在右侧编辑</span>
                        </div>
                        <div className={styles.levelRailList}>
                            {levels.map((level) => {
                                const activeBenefits = (level.benefits || []).filter(
                                    (benefit) => benefit.status === "active",
                                ).length;
                                return (
                                    <button
                                        aria-pressed={level.level === activeLevel.level}
                                        className={[
                                            styles.levelRailItem,
                                            level.level === activeLevel.level ? styles.levelRailItemActive : "",
                                        ]
                                            .filter(Boolean)
                                            .join(" ")}
                                        key={level.level}
                                        type="button"
                                        onClick={() => selectLevel(level)}
                                    >
                                        <span className={styles.levelRailItemTop}>
                                            <strong>VIP{level.level}</strong>
                                            <span
                                                className={[
                                                    styles.levelStatusDot,
                                                    level.status === "active" ? styles.levelStatusDotActive : "",
                                                ]
                                                    .filter(Boolean)
                                                    .join(" ")}
                                            />
                                        </span>
                                        <span className={styles.levelRailItemMeta}>
                                            <span>{level.status === "active" ? "启用" : "停用"}</span>
                                            {isP1 ? (
                                                <span>
                                                    {activeBenefits}/{level.benefits?.length || 0} 权益
                                                </span>
                                            ) : null}
                                        </span>
                                    </button>
                                );
                            })}
                        </div>
                    </nav>

                    <main className={styles.levelMain} data-testid={`vip-level-${activeLevel.level}`}>
                        <section className={styles.levelBaseSection} aria-label={`VIP${activeLevel.level}基础配置`}>
                            <div className={styles.panelHeading}>
                                <div>
                                    <span className={styles.panelEyebrow}>当前等级</span>
                                    <h3>
                                        VIP{activeLevel.level} · {activeLevel.name || `VIP${activeLevel.level}`}
                                    </h3>
                                </div>
                                <AdminSwitch
                                    checked={activeLevel.status === "active"}
                                    checkedLabel="启用"
                                    disabled={disabled}
                                    label={`VIP${activeLevel.level}状态`}
                                    uncheckedLabel="停用"
                                    onChange={(event) =>
                                        page.updateLevel(activeLevel.level, {
                                            status: event.target.checked ? "active" : "disabled",
                                        })
                                    }
                                />
                            </div>
                            <div className={styles.levelFields}>
                                <TextField
                                    disabled={disabled}
                                    label="名称"
                                    size="small"
                                    value={activeLevel.name}
                                    onChange={(event) =>
                                        page.updateLevel(activeLevel.level, { name: event.target.value })
                                    }
                                />
                                <TextField
                                    disabled={disabled}
                                    label="购买金币"
                                    size="small"
                                    slotProps={{ htmlInput: { min: 0, step: 1 } }}
                                    type="number"
                                    value={activeLevel.priceCoin}
                                    onChange={(event) =>
                                        page.updateLevel(activeLevel.level, { priceCoin: event.target.value })
                                    }
                                />
                                <TextField
                                    disabled={disabled}
                                    label="有效天数"
                                    size="small"
                                    slotProps={{ htmlInput: { min: 1, step: 1 } }}
                                    type="number"
                                    value={activeLevel.durationDays}
                                    onChange={(event) =>
                                        page.updateLevel(activeLevel.level, { durationDays: event.target.value })
                                    }
                                />
                                <ResourceGroupSelectField
                                    allowEmpty={isP1}
                                    disabled={disabled}
                                    drawerTitle={`选择 VIP${activeLevel.level} 奖励资源组`}
                                    emptyLabel="不配置等级礼包"
                                    groups={page.resourceGroups}
                                    label={isP1 ? "奖励资源组（可选）" : "奖励资源组"}
                                    placeholder={isP1 ? "可不配置等级礼包" : "请选择奖励资源组"}
                                    value={activeLevel.rewardResourceGroupId}
                                    onChange={(value) =>
                                        page.updateLevel(activeLevel.level, { rewardResourceGroupId: value })
                                    }
                                />
                                <TextField
                                    disabled={disabled}
                                    label="排序"
                                    size="small"
                                    slotProps={{ htmlInput: { min: 0, step: 1 } }}
                                    type="number"
                                    value={activeLevel.sortOrder}
                                    onChange={(event) =>
                                        page.updateLevel(activeLevel.level, { sortOrder: event.target.value })
                                    }
                                />
                            </div>
                        </section>

                        {isP1 ? (
                            <section className={styles.benefitsPanel} aria-label={`VIP${activeLevel.level}权益配置`}>
                                <div className={styles.benefitsToolbar}>
                                    <div className={styles.benefitsTitleBlock}>
                                        <h3>权益配置</h3>
                                        <span>
                                            已启用 {activeBenefitCount}/{benefits.length}
                                        </span>
                                    </div>
                                    <div className={styles.benefitsToolbarActions}>
                                        <TextField
                                            className={styles.benefitSearch}
                                            label="搜索权益"
                                            size="small"
                                            value={benefitQuery}
                                            onChange={(event) => setBenefitQuery(event.target.value)}
                                        />
                                        <FormControlLabel
                                            className={styles.selectAllControl}
                                            control={
                                                <Checkbox
                                                    checked={
                                                        benefits.length > 0 && activeBenefitCount === benefits.length
                                                    }
                                                    disabled={disabled || !benefits.length}
                                                    indeterminate={
                                                        activeBenefitCount > 0 && activeBenefitCount < benefits.length
                                                    }
                                                    size="small"
                                                    slotProps={{
                                                        input: { "aria-label": `VIP${activeLevel.level}权益全选` },
                                                    }}
                                                    onChange={(event) =>
                                                        page.updateAllBenefits(
                                                            activeLevel.level,
                                                            event.target.checked ? "active" : "disabled",
                                                        )
                                                    }
                                                />
                                            }
                                            label="全选"
                                        />
                                    </div>
                                </div>
                                <div aria-label="权益筛选" className={styles.filterBar}>
                                    {benefitFilterOptions.map(([value, label]) => (
                                        <button
                                            aria-pressed={benefitFilter === value}
                                            className={[
                                                styles.filterChip,
                                                benefitFilter === value ? styles.filterChipActive : "",
                                            ]
                                                .filter(Boolean)
                                                .join(" ")}
                                            key={value}
                                            type="button"
                                            onClick={() => setBenefitFilter(value)}
                                        >
                                            {label}
                                        </button>
                                    ))}
                                </div>
                                <div className={styles.benefitGroups}>
                                    {filteredGroups.length ? (
                                        filteredGroups.map((group) => (
                                            <section className={styles.benefitGroup} key={group.key}>
                                                <div className={styles.benefitGroupHeading}>
                                                    <span>{group.label}</span>
                                                    <span>
                                                        {group.items.filter((item) => item.status === "active").length}/
                                                        {group.items.length}
                                                    </span>
                                                </div>
                                                <div className={styles.benefitMatrix}>
                                                    {group.items.map((benefit) => (
                                                        <BenefitCard
                                                            benefit={benefit}
                                                            disabled={disabled}
                                                            key={benefit.benefitCode}
                                                            selected={
                                                                selectedBenefit?.benefitCode === benefit.benefitCode
                                                            }
                                                            onChange={(patch) =>
                                                                page.updateBenefit(
                                                                    activeLevel.level,
                                                                    benefit.benefitCode,
                                                                    patch,
                                                                )
                                                            }
                                                            onSelect={() => selectBenefit(benefit.benefitCode)}
                                                        />
                                                    ))}
                                                </div>
                                            </section>
                                        ))
                                    ) : (
                                        <div className={styles.emptyBenefits}>没有符合当前筛选条件的权益。</div>
                                    )}
                                </div>
                            </section>
                        ) : (
                            <div className={styles.classicNotice}>
                                Lalu 经典 VIP 只维护等级、价格、有效期和等级资源组，不使用 P1 权益矩阵。
                            </div>
                        )}
                    </main>

                    <aside className={styles.inspector} aria-label={showRules ? "VIP规则说明" : "权益详细设置"}>
                        {showRules || !isP1 ? (
                            <VipRulesPanel page={page} onBack={isP1 ? () => setShowRules(false) : undefined} />
                        ) : selectedBenefit ? (
                            <BenefitInspector
                                benefit={selectedBenefit}
                                disabled={disabled}
                                level={activeLevel.level}
                                page={page}
                            />
                        ) : (
                            <div className={styles.inspectorEmpty}>从中间选择一项权益后，在这里配置详细参数。</div>
                        )}
                    </aside>
                </DialogContent>

                <DialogActions className={styles.levelsDialogActions}>
                    <div className={styles.saveHint}>
                        <strong>整包保存</strong>
                        <span>切换等级不会丢失草稿，提交时一次保存全部 {levels.length} 个等级</span>
                    </div>
                    <div className={styles.footerActions}>
                        <Button disabled={page.saving} type="button" onClick={page.closeEditor}>
                            取消
                        </Button>
                        <Button
                            disabled={disabled}
                            startIcon={
                                page.saving ? (
                                    <CircularProgress color="inherit" size={16} />
                                ) : (
                                    <SaveOutlined fontSize="small" />
                                )
                            }
                            type="submit"
                            variant="primary"
                        >
                            保存全部配置
                        </Button>
                    </div>
                </DialogActions>
            </form>
        </Dialog>
    );
}

function BenefitCard({ benefit, disabled, onChange, onSelect, selected }) {
    return (
        <div className={[styles.benefitCard, selected ? styles.benefitCardSelected : ""].filter(Boolean).join(" ")}>
            <Checkbox
                checked={benefit.status === "active"}
                disabled={disabled}
                size="small"
                slotProps={{ input: { "aria-label": `${benefit.name}权益` } }}
                onChange={(event) => onChange({ status: event.target.checked ? "active" : "disabled" })}
            />
            <button aria-current={selected ? "true" : undefined} type="button" onClick={onSelect}>
                <span className={styles.benefitCardName}>{benefit.name}</span>
                <span className={styles.benefitCardSummary}>{benefitSummary(benefit)}</span>
            </button>
            <span className={benefit.status === "active" ? styles.benefitEnabledLabel : styles.benefitDisabledLabel}>
                {benefit.status === "active" ? "已启用" : "未启用"}
            </span>
        </div>
    );
}

function BenefitInspector({ benefit, disabled, level, page }) {
    const rebateBenefit = benefit.benefitCode === "daily_coin_rebate";
    const onlineNoticeBenefit = benefit.benefitCode === "online_global_notice";
    const expectedResourceType = vipBenefitResourceTypes[benefit.benefitCode] || "";
    const decorationBenefit = Boolean(expectedResourceType) || benefit.benefitType === "decoration";
    const selectableResources = expectedResourceType
        ? page.resources.filter((resource) => resource.resourceType === expectedResourceType)
        : page.resources;
    const metadataValid = Boolean(readVipBenefitMetadata(benefit.metadataJson));
    const onChange = (patch) => page.updateBenefit(level, benefit.benefitCode, patch);

    return (
        <div className={styles.inspectorBody}>
            <div className={styles.inspectorHeading}>
                <div>
                    <span className={styles.panelEyebrow}>当前权益</span>
                    <h3>{benefit.name}</h3>
                    <code>{benefit.benefitCode}</code>
                </div>
                <AdminSwitch
                    checked={benefit.status === "active"}
                    checkedLabel="启用"
                    disabled={disabled}
                    label={`${benefit.name}状态`}
                    uncheckedLabel="停用"
                    onChange={(event) => onChange({ status: event.target.checked ? "active" : "disabled" })}
                />
            </div>

            <section className={styles.inspectorSection}>
                <h4>业务参数</h4>
                {rebateBenefit ? (
                    <TextField
                        disabled={disabled || !metadataValid}
                        helperText={metadataValid ? "按 UTC 自然日结算" : "请先修正元数据JSON"}
                        label="每日返现金币"
                        required={benefit.status === "active"}
                        size="small"
                        slotProps={{ htmlInput: { min: 1, step: 1 } }}
                        type="number"
                        value={vipBenefitMetadataField(benefit.metadataJson, "coin_amount")}
                        onChange={(event) =>
                            onChange({
                                metadataJson: updateVipBenefitMetadataField(
                                    benefit.metadataJson,
                                    "coin_amount",
                                    event.target.value === "" ? "" : Number(event.target.value),
                                ),
                            })
                        }
                    />
                ) : null}
                {onlineNoticeBenefit ? (
                    <TextField
                        disabled={disabled || !metadataValid}
                        helperText={metadataValid ? "最多 256 个字符" : "请先修正元数据JSON"}
                        label="上线飘屏文案"
                        minRows={3}
                        multiline
                        size="small"
                        slotProps={{ htmlInput: { maxLength: 256 } }}
                        value={vipBenefitMetadataField(benefit.metadataJson, "message")}
                        onChange={(event) =>
                            onChange({
                                metadataJson: updateVipBenefitMetadataField(
                                    benefit.metadataJson,
                                    "message",
                                    event.target.value,
                                ),
                            })
                        }
                    />
                ) : null}
                {decorationBenefit ? (
                    <ResourceSelectField
                        disabled={disabled}
                        drawerTitle={`选择 ${benefit.name} 资源`}
                        label="绑定资源"
                        loading={page.resourcesLoading}
                        placeholder={benefit.status === "active" ? "请选择权益资源" : "停用时可暂不绑定"}
                        required={benefit.status === "active"}
                        resources={selectableResources}
                        value={benefit.resourceId}
                        onChange={(resourceId, resource) =>
                            onChange({ resourceId, resourceType: resource?.resourceType || "" })
                        }
                    />
                ) : null}
                {!rebateBenefit && !onlineNoticeBenefit && !decorationBenefit ? (
                    <p className={styles.noExtraFields}>该功能无额外业务参数，启用后按对应服务规则生效。</p>
                ) : null}
            </section>

            <section className={styles.inspectorSection}>
                <h4>应用规则</h4>
                <SwitchField
                    ariaLabel={`${benefit.name}体验卡可用`}
                    checked={!rebateBenefit && benefit.trialEnabled}
                    disabled={disabled || rebateBenefit}
                    label="体验卡可用"
                    onChange={(event) => onChange({ trialEnabled: event.target.checked })}
                />
                {decorationBenefit ? (
                    <SwitchField
                        ariaLabel={`${benefit.name}自动佩戴`}
                        checked={benefit.autoEquip}
                        disabled={disabled}
                        label="自动佩戴"
                        onChange={(event) => onChange({ autoEquip: event.target.checked })}
                    />
                ) : null}
            </section>

            <details className={styles.advancedSettings}>
                <summary>高级设置</summary>
                <div className={styles.advancedFields}>
                    <TextField
                        disabled={disabled || Boolean(expectedResourceType)}
                        label="权益类型"
                        select
                        size="small"
                        value={benefit.benefitType}
                        onChange={(event) =>
                            onChange({
                                autoEquip: event.target.value === "decoration" ? benefit.autoEquip : false,
                                benefitType: event.target.value,
                            })
                        }
                    >
                        <MenuItem value="decoration">装扮</MenuItem>
                        <MenuItem value="function">功能</MenuItem>
                    </TextField>
                    <TextField
                        disabled={disabled}
                        label="执行服务"
                        select
                        size="small"
                        value={benefit.executionScope}
                        onChange={(event) => onChange({ executionScope: event.target.value })}
                    >
                        <MenuItem value="wallet">钱包</MenuItem>
                        <MenuItem value="room">房间</MenuItem>
                        <MenuItem value="user">用户</MenuItem>
                        <MenuItem value="notice">通知</MenuItem>
                    </TextField>
                    {!decorationBenefit ? (
                        <ResourceSelectField
                            disabled={disabled}
                            drawerTitle={`选择 ${benefit.name} 资源`}
                            label="绑定资源（可选）"
                            loading={page.resourcesLoading}
                            placeholder="纯功能权益可不绑定"
                            required={false}
                            resources={page.resources}
                            value={benefit.resourceId}
                            onChange={(resourceId, resource) =>
                                onChange({ resourceId, resourceType: resource?.resourceType || "" })
                            }
                        />
                    ) : null}
                    <TextField
                        disabled={disabled}
                        label="元数据JSON"
                        minRows={4}
                        multiline
                        size="small"
                        value={benefit.metadataJson}
                        onChange={(event) => onChange({ metadataJson: event.target.value })}
                    />
                    <TextField
                        disabled={disabled}
                        label="排序"
                        size="small"
                        slotProps={{ htmlInput: { min: 0, step: 1 } }}
                        type="number"
                        value={benefit.sortOrder}
                        onChange={(event) => onChange({ sortOrder: event.target.value })}
                    />
                </div>
            </details>
        </div>
    );
}

function VipRulesPanel({ onBack, page }) {
    const notes = vipRuleNotes(page);
    return (
        <div className={styles.rulesPanel}>
            <div className={styles.inspectorHeading}>
                <div>
                    <span className={styles.panelEyebrow}>产品边界</span>
                    <h3>规则说明</h3>
                </div>
                {onBack ? (
                    <Button type="button" onClick={onBack}>
                        返回配置
                    </Button>
                ) : null}
            </div>
            <ol>
                {notes.map((note) => (
                    <li key={note}>{note}</li>
                ))}
            </ol>
        </div>
    );
}

function SwitchField({ ariaLabel, checked, disabled, label, onChange }) {
    return (
        <div className={styles.switchField}>
            <span>{label}</span>
            <AdminSwitch
                checked={checked}
                checkedLabel="开启"
                disabled={disabled}
                label={ariaLabel || label}
                uncheckedLabel="关闭"
                onChange={onChange}
            />
        </div>
    );
}

function groupVisibleBenefits(benefits, query, filter) {
    // 目录分组只控制可见密度，不写回业务字段；权益类型和执行服务仍以服务端契约为准。
    const keyword = query.trim().toLocaleLowerCase();
    const visible = benefits.filter((benefit) => {
        const queryMatches =
            !keyword ||
            benefit.name.toLocaleLowerCase().includes(keyword) ||
            benefit.benefitCode.toLocaleLowerCase().includes(keyword);
        const filterMatches =
            filter === "all" ||
            (filter === "active" && benefit.status === "active") ||
            (filter === "disabled" && benefit.status === "disabled") ||
            benefit.benefitType === filter;
        return queryMatches && filterMatches;
    });
    return benefitGroupDefinitions
        .map(([key, label]) => ({
            items: visible.filter((benefit) => benefitGroupKey(benefit) === key),
            key,
            label,
        }))
        .filter((group) => group.items.length);
}

function benefitGroupKey(benefit) {
    if (benefit.benefitType === "decoration") return "decoration";
    if (["wallet", "notice", "room", "user"].includes(benefit.executionScope)) return benefit.executionScope;
    return "user";
}

function benefitSummary(benefit) {
    if (benefit.benefitCode === "daily_coin_rebate") {
        const amount = vipBenefitMetadataField(benefit.metadataJson, "coin_amount");
        return amount ? `每日 ${formatNumber(amount)} 金币` : "未配置返现金额";
    }
    if (benefit.benefitCode === "online_global_notice") {
        const message = String(vipBenefitMetadataField(benefit.metadataJson, "message") || "");
        return message ? truncateText(message, 18) : "未配置通知文案";
    }
    if (benefit.resourceId) return `已绑定资源 · ${benefit.resourceId}`;
    if (benefit.benefitType === "decoration") return "未绑定资源";
    return benefit.trialEnabled ? "体验卡可用" : "会员权益";
}

function vipRuleNotes(page) {
    const p1 = page.program.programType === "tiered_privilege_v1";
    return [
        `当前配置只作用于 ${page.appCode || "当前 App"}，等级、价格和权益不会跨 App 共用。`,
        p1
            ? "Fami 购买高等级后立即替换低等级，并从购买时重新计时；原低等级剩余时间丢弃。"
            : "Lalu 沿用经典 VIP：同级和高等级购买保留剩余时间并续期。",
        "低等级购买不覆盖当前高等级；同等级购买按体系规则续期。",
        "VIP 体验卡走背包佩戴，可自由切换；未佩戴体验卡的剩余时间正常保留，金币返现不随体验卡生效。",
        "进房通知只在当前房间展示；上线全服通知由客户端按本次进程记录当日展示状态。",
        "金币返现按项目统一的 UTC 自然日结算；跨服务时间使用 Unix 毫秒。",
        "防踢、防禁言只拦截普通房主或管理员操作，不绕过平台风控、平台封禁和超级管理员。",
    ];
}

function truncateText(value, maxLength) {
    return value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;
}

function vipColumns() {
    return [
        {
            key: "level",
            label: "等级",
            render: (item) => <span className={styles.levelTableName}>VIP{item.level}</span>,
            width: "minmax(110px, 0.7fr)",
        },
        {
            key: "status",
            label: "状态",
            render: (item) => (
                <span
                    className={[
                        styles.statusBadge,
                        item.status === "active" ? styles.statusActive : styles.statusDisabled,
                    ].join(" ")}
                >
                    {item.status === "active" ? "启用" : "停用"}
                </span>
            ),
            width: "minmax(110px, 0.7fr)",
        },
        {
            key: "price",
            label: "购买金币",
            render: (item) => formatNumber(item.priceCoin),
            width: "minmax(140px, 1fr)",
        },
        {
            key: "duration",
            label: "有效期",
            render: (item) => `${Math.round(Number(item.durationMs || 0) / 86400000)} 天`,
            width: "minmax(120px, 0.8fr)",
        },
        {
            key: "updatedAtMs",
            label: "更新时间",
            render: (item) => formatMillis(item.updatedAtMs),
            width: "minmax(180px, 1.2fr)",
        },
    ];
}

function SummaryItem({ children, label }) {
    return (
        <div className={styles.summaryItem}>
            <span className={styles.summaryLabel}>{label}</span>
            <span className={styles.summaryValue}>{children}</span>
        </div>
    );
}

function formatNumber(value) {
    const number = Number(value || 0);
    return Number.isFinite(number) ? number.toLocaleString("zh-CN") : "-";
}
