import { z } from 'zod';

export const COUPON_TYPES = ['percent', 'fixed', 'bogo'] as const;
export const COUPON_STATUSES = ['active', 'archived'] as const;
export const ORDER_TYPES = ['dine-in', 'takeaway', 'delivery'] as const;
export const COUPON_CHANNELS = ['chat', 'whatsapp', 'storefront', 'voice'] as const;

const bogoConfigSchema = z.object({
  buy_target_type: z.enum(['item', 'category']).optional(),
  buy_target_id: z.string().uuid().optional(),
  get_target_type: z.enum(['item', 'category']).optional(),
  get_target_id: z.string().uuid().optional(),
  get_discount_kind: z.enum(['free', 'percent']).optional(),
  get_discount_percent: z.number().min(0).max(100).optional(),
}).partial();

const couponBaseSchema = z.object({
  code: z.string().trim().min(2).max(40)
    .regex(/^[A-Za-z0-9_-]+$/, 'Code may only contain letters, numbers, underscores and dashes'),
  display_name: z.string().trim().max(120).optional(),
  description: z.string().trim().max(500).optional(),
  type: z.enum(COUPON_TYPES),
  value: z.number().nonnegative().default(0),
  bogo_config: bogoConfigSchema.optional(),
  valid_from: z.string().datetime().optional().nullable(),
  valid_until: z.string().datetime().optional().nullable(),
  total_redemption_cap: z.number().int().positive().optional().nullable(),
  per_customer_cap: z.number().int().positive().optional().nullable(),
  min_order_value: z.number().nonnegative().default(0),
  applicable_order_types: z.array(z.enum(ORDER_TYPES)).min(1).default(['dine-in', 'takeaway', 'delivery']),
  applicable_channels: z.array(z.enum(COUPON_CHANNELS)).min(1).default(['chat', 'whatsapp', 'storefront']),
  applicable_branches: z.array(z.string().uuid()).default([]),
  branch_id: z.string().uuid().optional(),
  stack_with_loyalty: z.boolean().default(true),
  stack_with_gift_card: z.boolean().default(true),
  status: z.enum(COUPON_STATUSES).default('active'),
});

export const createCouponSchema = couponBaseSchema.superRefine((d, ctx) => {
  if (d.type === 'percent' && (d.value <= 0 || d.value > 100)) {
    ctx.addIssue({ code: 'custom', message: 'Percent value must be between 0 and 100', path: ['value'] });
  }
  if (d.type === 'fixed' && d.value <= 0) {
    ctx.addIssue({ code: 'custom', message: 'Fixed amount must be greater than 0', path: ['value'] });
  }
  if (d.valid_from && d.valid_until && new Date(d.valid_from) > new Date(d.valid_until)) {
    ctx.addIssue({ code: 'custom', message: 'Valid-from must come before valid-until', path: ['valid_until'] });
  }
});

export const updateCouponSchema = couponBaseSchema.partial();

export const bulkImportSchema = z.object({
  branch_id: z.string().uuid(),
  rows: z.array(couponBaseSchema).min(1).max(500),
});

export const previewCouponSchema = z.object({
  code: z.string().trim().min(1).max(40),
  delivery_type: z.enum(ORDER_TYPES),
  items: z.array(z.object({
    menu_item_id: z.string().uuid(),
    name: z.string().optional(),
    quantity: z.number().int().positive(),
    price: z.number().nonnegative(),
    category_id: z.string().uuid().optional(),
  })).min(1),
});

export type CreateCouponInput = z.infer<typeof createCouponSchema>;
export type UpdateCouponInput = z.infer<typeof updateCouponSchema>;
export type BulkImportInput = z.infer<typeof bulkImportSchema>;
export type PreviewCouponInput = z.infer<typeof previewCouponSchema>;
