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 { useEffect, useMemo, useRef, useState } from "react";
import { Button } from "@/shared/ui/Button.jsx";
import {
    applyGiftHostDiamondRatio,
    applyDynamicStrategyDefaults,
    configToForm,
    correctAllStageProbabilities,
    formToConfig,
    giftHostDiamondRatioForPool,
    nextStageMultiplier,
    stageSummary,
    validateLuckyGiftForm,
} from "../configForm.js";
import {
    buildExperimentCreateRequest,
    experimentDraft,
    formatTrafficPercent,
    validateExperimentDraft,
} from "../experimentForm.js";
import { formatNumber, formatPercent } from "../format.js";
import { LuckyGiftConfigSections } from "./LuckyGiftConfigSections.jsx";
import { LuckyGiftExperimentFields } from "./LuckyGiftExperimentFields.jsx";
import { LuckyGiftStageDesigner } from "./LuckyGiftStageDesigner.jsx";

export function LuckyGiftConfigDialog({
    appOptions = [],
    config,
    giftHostDiamondRatiosByApp = {},
    mode = "edit",
    onClose,
    onSubmit,
    saving,
}) {
    const isExperiment = mode === "experiment";
    const isCreate = mode === "create";
    // 实验组配置由 owner 原子发布并立即参与分流开奖，enabled 强制 true 且开关锁定；
    // 以当前行配置为初始值，运营在其上修改出实验组版本。
    const [form, setForm] = useState(() => {
        const initial = configToForm(isExperiment ? { ...config, enabled: true } : config);
        const ratio = resolveHostDiamondRatio(giftHostDiamondRatiosByApp, initial);
        if (initial.strategy_version !== "dynamic_v3" || ratio === null) return initial;
        // 未发布草稿按接口真实比例重建资金基线；已发布版本只替换历史快照中的主播钻石比例，
        // 保留运营现有的目标 RTP/奖池比例，若二者不闭合则由发布校验明确提示。
        const rebalance =
            isCreate ||
            (config.is_default ?? config.isDefault) === true ||
            Number(config.rule_version ?? config.ruleVersion ?? 0) <= 0;
        return applyGiftHostDiamondRatio(initial, ratio, { rebalance });
    });
    const [experiment, setExperiment] = useState(experimentDraft);
    const [activeStage, setActiveStage] = useState("novice");
    const [validationErrors, setValidationErrors] = useState([]);
    const validationRef = useRef(null);

    const stageSummaries = useMemo(() => form.stages.map((stage) => stageSummary(stage, form)), [form]);
    const activeStageKey = form.stages.some((stage) => stage.stage === activeStage)
        ? activeStage
        : form.stages[0]?.stage;
    const activeStageConfig = form.stages.find((stage) => stage.stage === activeStageKey);
    const activeSummary = stageSummaries.find((summary) => summary.stageKey === activeStageKey);
    const normalStageConfig = form.stages.find((stage) => stage.stage === "normal");

    useEffect(() => {
        if (!validationErrors.length) return;
        // 保存按钮位于固定底栏；失败后把焦点送回错误摘要，避免键盘或读屏用户停留在无变化的按钮上。
        validationRef.current?.focus();
    }, [validationErrors]);

    const updateField = (field, value) => {
        setValidationErrors([]);
        setForm((current) => {
            const next = { ...current, [field]: value };
            const hostDiamondRatio = resolveHostDiamondRatio(giftHostDiamondRatiosByApp, next);
            if (field === "strategy_version" && value === "dynamic_v3" && current.strategy_version !== "dynamic_v3") {
                const dynamicDraft = applyDynamicStrategyDefaults(next, { anchorRatePercent: hostDiamondRatio });
                // 常规模式安全草稿保持停用；实验模式下实验组必须直接可运行，启用态不允许被安全草稿覆盖回停用。
                return isExperiment ? { ...dynamicDraft, enabled: true } : dynamicDraft;
            }
            if (["app_code", "pool_id"].includes(field) && next.strategy_version === "dynamic_v3") {
                return applyGiftHostDiamondRatio(next, hostDiamondRatio, { rebalance: true });
            }
            // 目标 RTP 决定各奖档概率的闭合解，改动后全部阶段重算，避免展示的概率和将要发布的值不一致。
            return field === "target_rtp_percent" ? correctAllStageProbabilities(next) : next;
        });
    };

    const updateStageField = (stageKey, field, value) => {
        setValidationErrors([]);
        setForm((current) => ({
            ...current,
            stages: current.stages.map((stage) => (stage.stage === stageKey ? { ...stage, [field]: value } : stage)),
        }));
    };

    const updateStageTier = (stageKey, tierIndex, patch) => {
        setValidationErrors([]);
        setForm((current) =>
            correctAllStageProbabilities({
                ...current,
                stages: current.stages.map((stage) =>
                    stage.stage === stageKey
                        ? {
                              ...stage,
                              tiers: stage.tiers.map((tier, index) =>
                                  index === tierIndex ? { ...tier, ...patch } : tier,
                              ),
                          }
                        : stage,
                ),
            }),
        );
    };

    const addStageTier = (stageKey) => {
        setValidationErrors([]);
        setForm((current) =>
            correctAllStageProbabilities({
                ...current,
                stages: current.stages.map((stage) =>
                    stage.stage === stageKey
                        ? {
                              ...stage,
                              tiers: [
                                  ...stage.tiers,
                                  {
                                      enabled: true,
                                      // 10 倍以上先写入服务端要求的高倍率安全标记；实际开奖仍以实时余额和返奖上限
                                      // 判断是否付得起，前端默认值不能被解释成“高余额时一定会发”。
                                      highWaterOnly: nextStageMultiplier(stage.tiers) >= 10,
                                      multiplier: String(nextStageMultiplier(stage.tiers)),
                                      probabilityPercent: "0",
                                      tierId: "",
                                  },
                              ],
                          }
                        : stage,
                ),
            }),
        );
    };

    const removeStageTier = (stageKey, tierIndex) => {
        setValidationErrors([]);
        setForm((current) =>
            correctAllStageProbabilities({
                ...current,
                stages: current.stages.map((stage) =>
                    stage.stage === stageKey
                        ? { ...stage, tiers: stage.tiers.filter((_, index) => index !== tierIndex) }
                        : stage,
                ),
            }),
        );
    };

    const updateExperimentField = (field, value) => {
        setValidationErrors([]);
        setExperiment((current) => ({ ...current, [field]: value }));
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        // 实验模式即使开关被绕过也按启用校验：提交的实验组配置必须直接可运行，
        // 校验口径与最终 payload 完全一致，避免“校验通过、发布被拒”的错位。
        const submittedForm = isExperiment ? { ...form, enabled: true } : form;
        const formErrors = isExperiment
            ? [...validateExperimentDraft(experiment), ...validateLuckyGiftForm(submittedForm)]
            : validateLuckyGiftForm(submittedForm);
        const errors =
            submittedForm.strategy_version === "dynamic_v3" &&
            resolveHostDiamondRatio(giftHostDiamondRatiosByApp, submittedForm) === null
                ? ["未读取到当前应用的主播钻石比例，请刷新页面后再发布", ...formErrors]
                : formErrors;
        if (errors.length) {
            setValidationErrors(errors);
            return;
        }
        if (isExperiment) {
            onSubmit(buildExperimentCreateRequest(experiment, formToConfig(config, submittedForm)));
            return;
        }
        onSubmit(formToConfig(config, form));
    };

    const title = isExperiment
        ? "创建 AB 实验"
        : isCreate
          ? "添加幸运礼物配置"
          : config.is_default
            ? "发布幸运礼物配置"
            : "新增幸运礼物版本";

    return (
        <Dialog
            aria-labelledby="ops-config-dialog-title"
            fullWidth
            maxWidth={false}
            open
            scroll="paper"
            slotProps={{ paper: { className: "ops-config-dialog-paper" } }}
            onClose={saving ? undefined : onClose}
        >
            <form className="ops-config-form" onSubmit={handleSubmit}>
                <DialogTitle className="ops-config-title" id="ops-config-dialog-title">
                    <span>{title}</span>
                    <small>
                        {form.app_code || "-"} / {form.pool_id || "default"} /{" "}
                        {isExperiment
                            ? `对照组为 ${config.strategy_version || "fixed_v2"} v${config.rule_version ?? "-"}，本表单发布为实验组新版本`
                            : config.is_default || isCreate
                              ? "默认草稿"
                              : `当前版本 v${config.rule_version ?? "-"}`}
                    </small>
                </DialogTitle>
                <dl className="ops-config-summary" aria-label="配置摘要">
                    <ConfigMetric label="应用" value={form.app_code || "-"} />
                    <ConfigMetric label="奖池" value={form.pool_id || "default"} />
                    <ConfigMetric label="开奖策略" value={form.strategy_version} />
                    <ConfigMetric label="基础返还目标" value={formatPercent(Number(form.target_rtp_percent))} />
                    <ConfigMetric
                        label={form.strategy_version === "dynamic_v3" ? "资金拆分" : "奖池比例"}
                        value={
                            form.strategy_version === "dynamic_v3"
                                ? `奖池 ${form.pool_rate_percent}% / 平台 ${form.profit_rate_percent}% / 主播钻石 ${form.anchor_rate_percent}%（接口读取）`
                                : `${form.pool_rate_percent}%`
                        }
                    />
                    <ConfigMetric
                        label={form.strategy_version === "dynamic_v3" ? "每轮观察流水" : "V2 窗口配置"}
                        value={formatNumber(Number(form.settlement_window_wager))}
                    />
                    <ConfigMetric
                        label={isExperiment ? "实验组流量" : "发布状态"}
                        value={
                            isExperiment
                                ? formatTrafficPercent(Number(experiment.trafficPercent))
                                : form.enabled
                                  ? "启用"
                                  : "停用"
                        }
                    />
                </dl>
                <DialogContent className="ops-config-dialog-content" dividers>
                    {validationErrors.length ? (
                        <div
                            aria-live="assertive"
                            className="ops-config-validation"
                            ref={validationRef}
                            role="alert"
                            tabIndex={-1}
                        >
                            <strong>{isExperiment ? "实验不能创建" : "配置不能发布"}</strong>
                            <ul>
                                {validationErrors.map((message) => (
                                    <li key={message}>{message}</li>
                                ))}
                            </ul>
                        </div>
                    ) : null}

                    {isExperiment ? (
                        <LuckyGiftExperimentFields
                            disabled={saving}
                            draft={experiment}
                            onChange={updateExperimentField}
                        />
                    ) : null}

                    <div className="ops-config-layout">
                        <LuckyGiftConfigSections
                            appOptions={appOptions}
                            experimentMode={isExperiment}
                            form={form}
                            hostDiamondRatioAvailable={
                                resolveHostDiamondRatio(giftHostDiamondRatiosByApp, form) !== null
                            }
                            isCreate={isCreate}
                            onChange={updateField}
                        />
                        <LuckyGiftStageDesigner
                            activeStageConfig={activeStageConfig}
                            activeStageKey={activeStageKey}
                            activeSummary={activeSummary}
                            normalStageConfig={normalStageConfig}
                            stageSummaries={stageSummaries}
                            strategyVersion={form.strategy_version}
                            onAddTier={addStageTier}
                            onRemoveTier={removeStageTier}
                            onStageChange={setActiveStage}
                            onStageFieldChange={updateStageField}
                            onTierChange={updateStageTier}
                        />
                    </div>
                </DialogContent>
                <DialogActions className="ops-config-dialog-actions">
                    <Button disabled={saving} onClick={onClose}>
                        取消
                    </Button>
                    <Button disabled={saving} type="submit" variant="primary">
                        {saving ? (isExperiment ? "创建中" : "保存中") : isExperiment ? "创建实验" : "保存配置"}
                    </Button>
                </DialogActions>
            </form>
        </Dialog>
    );
}

function resolveHostDiamondRatio(ratiosByApp, form) {
    const appCode = String(form?.app_code || "")
        .trim()
        .toLowerCase();
    return giftHostDiamondRatioForPool(ratiosByApp?.[appCode], form?.pool_id);
}

function ConfigMetric({ label, value }) {
    return (
        <div className="ops-config-metric">
            <dt>{label}</dt>
            <dd>{value}</dd>
        </div>
    );
}
