import type { Transaction } from "@shared/lib/types";
import { z } from "zod";
import { EffectType, LootType } from "@shared/lib/constants";

// Helper Schemas
const LootTableItemSchema = z.object({
    type: z.nativeEnum(LootType),
    weight: z.number(),
    amount: z.number().optional(),
    itemId: z.number().optional(),
    minAmount: z.number().optional(),
    maxAmount: z.number().optional(),
    message: z.string().optional(),
});

const DurationSchema = z.object({
    durationSeconds: z.number().optional(),
    durationMinutes: z.number().optional(),
    durationHours: z.number().optional(),
});

// Effect Schemas
const AddXpSchema = z.object({
    type: z.literal(EffectType.ADD_XP),
    amount: z.number().positive(),
});

const AddBalanceSchema = z.object({
    type: z.literal(EffectType.ADD_BALANCE),
    amount: z.number(),
});

const ReplyMessageSchema = z.object({
    type: z.literal(EffectType.REPLY_MESSAGE),
    message: z.string(),
});

const XpBoostSchema = DurationSchema.extend({
    type: z.literal(EffectType.XP_BOOST),
    multiplier: z.number(),
});

const TempRoleSchema = DurationSchema.extend({
    type: z.literal(EffectType.TEMP_ROLE),
    roleId: z.string(),
});

const ColorRoleSchema = z.object({
    type: z.literal(EffectType.COLOR_ROLE),
    roleId: z.string(),
});

const LootboxSchema = z.object({
    type: z.literal(EffectType.LOOTBOX),
    pool: z.array(LootTableItemSchema),
});

// Union Schema
export const EffectPayloadSchema = z.discriminatedUnion('type', [
    AddXpSchema,
    AddBalanceSchema,
    ReplyMessageSchema,
    XpBoostSchema,
    TempRoleSchema,
    ColorRoleSchema,
    LootboxSchema,
]);

export type ValidatedEffectPayload = z.infer<typeof EffectPayloadSchema>;

export type EffectHandler = (userId: string, effect: any, txFn: Transaction) => Promise<any>;
