import { z } from "zod";

const trackSchema = z.enum(["wealth", "game", "charm"]);
const statusSchema = z.enum(["active", "disabled"]);
const numberInput = z.union([z.string(), z.number()]);

export const levelTrackFormSchema = z
    .object({
        displayConfigJson: z.string().optional(),
        name: z.string().trim().min(1, "请输入等级名称").max(64, "等级名称不能超过 64 个字符"),
        sortOrder: numberInput.optional(),
        status: statusSchema,
    })
    .superRefine((value, context) => {
        validateInteger(context, "sortOrder", value.sortOrder || 0, "排序必须是整数");
    });

export const levelRuleFormSchema = z
    .object({
        avatarFrameResourceId: numberInput.optional(),
        level: numberInput,
        longBadgeResourceId: numberInput.optional(),
        name: z.string().trim().min(1, "请输入等级展示名称").max(64, "等级展示名称不能超过 64 个字符"),
        requiredValue: numberInput,
        rewardResourceGroupId: numberInput.optional(),
        shortBadgeResourceId: numberInput.optional(),
        sortOrder: numberInput.optional(),
        status: statusSchema,
        track: trackSchema,
    })
    .superRefine((value, context) => {
        validateNonNegativeInteger(context, "level", value.level, "等级必须是非负整数");
        validateNonNegativeInteger(context, "requiredValue", value.requiredValue, "升级数值必须是非负整数");
        validateOptionalId(context, "avatarFrameResourceId", value.avatarFrameResourceId, "等级头像框素材必须是有效资源");
        validateOptionalId(context, "longBadgeResourceId", value.longBadgeResourceId, "长徽章素材必须是有效资源");
        validateOptionalId(context, "rewardResourceGroupId", value.rewardResourceGroupId, "升级礼物必须是有效资源组");
        validateOptionalId(context, "shortBadgeResourceId", value.shortBadgeResourceId, "短徽章素材必须是有效资源");
        validateInteger(context, "sortOrder", value.sortOrder || 0, "排序必须是整数");
    });

export const levelTierFormSchema = z
    .object({
        displayAvatarFrameResourceId: numberInput.optional(),
        displayBadgeResourceId: numberInput.optional(),
        displayConfigJson: z.string().optional(),
        maxLevel: numberInput,
        minLevel: numberInput,
        name: z.string().trim().min(1, "请输入等级层名称").max(64, "等级层名称不能超过 64 个字符"),
        rewardResourceGroupId: numberInput.optional(),
        status: statusSchema,
        track: trackSchema,
    })
    .superRefine((value, context) => {
        const minLevel = Number(value.minLevel);
        const maxLevel = Number(value.maxLevel);

        validateNonNegativeInteger(context, "minLevel", value.minLevel, "起始等级必须是非负整数");
        validateNonNegativeInteger(context, "maxLevel", value.maxLevel, "结束等级必须是非负整数");
        if (Number.isInteger(minLevel) && Number.isInteger(maxLevel) && maxLevel < minLevel) {
            context.addIssue({ code: "custom", message: "结束等级不能小于起始等级", path: ["maxLevel"] });
        }
        validateOptionalId(
            context,
            "displayAvatarFrameResourceId",
            value.displayAvatarFrameResourceId,
            "头像框素材必须是有效资源",
        );
        validateOptionalId(context, "displayBadgeResourceId", value.displayBadgeResourceId, "徽章素材必须是有效资源");
        validateOptionalId(context, "rewardResourceGroupId", value.rewardResourceGroupId, "升级礼物必须是有效资源组");
    });

export type LevelRuleForm = z.infer<typeof levelRuleFormSchema>;
export type LevelTierForm = z.infer<typeof levelTierFormSchema>;
export type LevelTrackForm = z.infer<typeof levelTrackFormSchema>;

function validatePositiveInteger(context: z.RefinementCtx, path: string, value: unknown, message: string) {
    const numeric = Number(value);
    if (!Number.isInteger(numeric) || numeric <= 0) {
        context.addIssue({ code: "custom", message, path: [path] });
    }
}

function validateNonNegativeInteger(context: z.RefinementCtx, path: string, value: unknown, message: string) {
    const numeric = Number(value);
    if (!Number.isInteger(numeric) || numeric < 0) {
        context.addIssue({ code: "custom", message, path: [path] });
    }
}

function validateInteger(context: z.RefinementCtx, path: string, value: unknown, message: string) {
    const numeric = Number(value);
    if (!Number.isInteger(numeric)) {
        context.addIssue({ code: "custom", message, path: [path] });
    }
}

function validateOptionalId(context: z.RefinementCtx, path: string, value: unknown, message: string) {
    const raw = String(value ?? "").trim();
    if (!raw) {
        return;
    }
    validatePositiveInteger(context, path, raw, message);
}
