import { z } from "zod";

const rewardTypes = ["coin", "gift", "prop", "dress"] as const;
const propRewardTypes = new Set(["prop", "dress"]);
const wheelTierCounts: Record<string, number> = {
    advanced: 12,
    classic: 8,
    luxury: 8,
};

const wheelTierSchema = z.object({
    displayName: z.string().trim().min(1, "奖品名称不能为空").max(80, "奖品名称不能超过 80 个字符"),
    enabled: z.boolean(),
    metadataJson: z.string().trim().default("{}"),
    probabilityPercent: z.coerce.number().min(0, "概率不能小于 0").max(100, "概率不能超过 100%"),
    rewardCoins: z.coerce.number().int("金币数量必须是整数").min(0, "金币数量不能小于 0"),
    rewardCount: z.coerce.number().int("奖励数量必须是整数").min(0, "奖励数量不能小于 0"),
    rewardId: z.string().trim().default(""),
    rewardType: z.enum(rewardTypes),
    rtpValueCoins: z.coerce.number().int("RTP 价值必须是整数").min(0, "RTP 价值不能小于 0"),
    tierId: z.string().trim().min(1, "档位 ID 不能为空").max(64, "档位 ID 不能超过 64 个字符"),
});

export const wheelConfigFormSchema = z
    .object({
        drawPriceCoins: z.coerce.number().int("单抽价格必须是整数").gt(0, "单抽价格必须大于 0"),
        effectiveFromMs: z.coerce.number().int("生效时间必须是毫秒整数").min(0, "生效时间不能小于 0"),
        enabled: z.boolean(),
        initialPoolCoins: z.coerce.number().int("初始奖池必须是整数").min(0, "初始奖池不能小于 0"),
        maxSingleRTPPayout: z.coerce.number().int("单次 RTP 上限必须是整数").min(0, "单次 RTP 上限不能小于 0"),
        poolRatePercent: z.coerce.number().min(0, "入池比例不能小于 0").max(100, "入池比例不能超过 100%"),
        poolReserveCoins: z.coerce.number().int("奖池保底必须是整数").min(0, "奖池保底不能小于 0"),
        settlementWindowDraws: z.coerce.number().int("结算窗口必须是整数").gt(0, "结算窗口必须大于 0"),
        targetRTPPercent: z.coerce.number().min(0, "RTP 不能小于 0").max(100, "RTP 不能超过 100%"),
        tiers: z.array(wheelTierSchema).min(1, "必须配置奖品档位"),
        wheelId: z.string().trim().min(1, "转盘 ID 不能为空").max(64, "转盘 ID 不能超过 64 个字符"),
    })
    .superRefine((value, context) => {
        const expectedCount = wheelTierCounts[value.wheelId] || wheelTierCounts.classic;
        if (value.tiers.length !== expectedCount) {
            context.addIssue({
                code: "custom",
                message: `${value.wheelId} 转盘必须配置 ${expectedCount} 个奖品档位`,
                path: ["tiers"],
            });
        }

        const totalPPM = value.tiers.reduce((sum, tier) => sum + Math.round(tier.probabilityPercent * 10_000), 0);
        if (totalPPM !== 1_000_000) {
            context.addIssue({
                code: "custom",
                message: "奖品档位概率合计必须等于 100%",
                path: ["tiers"],
            });
        }

        value.tiers.forEach((tier, index) => {
            if (tier.enabled && tier.probabilityPercent <= 0) {
                context.addIssue({
                    code: "custom",
                    message: "启用奖品的概率必须大于 0",
                    path: ["tiers", index, "probabilityPercent"],
                });
            }
            if (tier.rewardType === "coin" && tier.rewardCoins <= 0) {
                context.addIssue({
                    code: "custom",
                    message: "金币档 reward_coins 必须大于 0",
                    path: ["tiers", index, "rewardCoins"],
                });
            }
            if (tier.rewardType === "gift" && !tier.rewardId) {
                context.addIssue({
                    code: "custom",
                    message: "礼物档 reward_id 不能为空",
                    path: ["tiers", index, "rewardId"],
                });
            }
            if (propRewardTypes.has(tier.rewardType) && !tier.rewardId) {
                context.addIssue({
                    code: "custom",
                    message: "道具或装扮档 reward_id 不能为空",
                    path: ["tiers", index, "rewardId"],
                });
            }
            if (propRewardTypes.has(tier.rewardType) && tier.rtpValueCoins !== 0) {
                context.addIssue({
                    code: "custom",
                    message: "道具或装扮不计入 RTP，RTP 价值必须为 0",
                    path: ["tiers", index, "rtpValueCoins"],
                });
            }
            if (tier.metadataJson) {
                try {
                    JSON.parse(tier.metadataJson);
                } catch {
                    context.addIssue({
                        code: "custom",
                        message: "扩展 JSON 格式不正确",
                        path: ["tiers", index, "metadataJson"],
                    });
                }
            }
        });
    });

export type WheelConfigForm = z.infer<typeof wheelConfigFormSchema>;
