import { z } from 'zod';
import { promoFunder } from '@/lib/enums/promo-funder';
import { promoKind } from '@/lib/enums/promo-kind';
import { promoStatus } from '@/lib/enums/promo-status';

const eligibilitySchema = z.object({
  firstPurchaseOnly: z.boolean().optional(),
  clubOnly: z.boolean().optional(),
  userAllowlist: z.array(z.uuid()).optional(),
});

const scopeSchema = z.discriminatedUnion('kind', [
  z.object({ kind: z.literal('all') }),
  z.object({ kind: z.literal('deals'), dealIds: z.array(z.uuid()).min(1) }),
  z.object({ kind: z.literal('categories'), categoryIds: z.array(z.uuid()).min(1) }),
  z.object({ kind: z.literal('tags'), tagIds: z.array(z.uuid()).min(1) }),
  z.object({ kind: z.literal('vendor'), vendorId: z.uuid() }),
]);

export const promoRulesSchema = z.object({
  scope: scopeSchema,
  eligibility: eligibilitySchema,
});

export const createPromoCodeBaseSchema = z.object({
  code: z
    .string()
    .min(3)
    .max(64)
    .regex(/^[A-Za-z0-9_-]+$/),
  kind: promoKind.schema,
  valueBps: z.number().int().min(1).max(10000).optional(),
  valueAmount: z.number().int().positive().optional(),
  maxCapAmount: z.number().int().positive().optional(),
  bogoBuy: z.number().int().positive().optional(),
  bogoGetFree: z.number().int().positive().optional(),
  funder: promoFunder.schema,
  vendorId: z.uuid().nullable().optional(),
  status: promoStatus.schema.default('active'),
  validFrom: z.iso.datetime().optional(),
  validUntil: z.iso.datetime().optional(),
  minSubtotal: z.number().int().nonnegative().optional(),
  maxSubtotal: z.number().int().positive().optional(),
  totalCap: z.number().int().positive().optional(),
  perUserCap: z.number().int().positive().default(1),
  rulesJson: promoRulesSchema,
  description: z.string().max(280).optional(),
});

export const createPromoCodeSchema = createPromoCodeBaseSchema
  .refine((v) => (v.kind === 'percentage' ? v.valueBps != null : true), {
    message: 'valueBps required for percentage',
    path: ['valueBps'],
  })
  .refine((v) => (v.kind === 'fixed_amount' ? v.valueAmount != null : true), {
    message: 'valueAmount required for fixed_amount',
    path: ['valueAmount'],
  })
  .refine((v) => (v.kind === 'bogo' ? v.bogoBuy != null && v.bogoGetFree != null : true), {
    message: 'bogoBuy and bogoGetFree required for bogo',
    path: ['bogoBuy'],
  });

export const previewPromoSchema = z.object({
  code: z.string().min(1).max(64),
  cartId: z.uuid().optional(),
});
