/**
 * Zod schemas for the cart API routes.
 *
 * All API boundary inputs parse through these schemas before touching any
 * business logic (zod-at-boundary law, md-server-dev §1).
 *
 * Shared between client (type inference) and server (validation).
 */

import { z } from 'zod';

// ---------------------------------------------------------------------------
// Shared fields
// ---------------------------------------------------------------------------

const uuidSchema = z.uuid('Must be a valid UUID');
const qtySchema = z.int().min(1).max(100);

// ---------------------------------------------------------------------------
// POST /api/cart/items   — add/upsert a line item
// ---------------------------------------------------------------------------

export const addCartItemBodySchema = z.object({
  dealSkuId: uuidSchema,
  qty: qtySchema,
  csrfToken: z.string().min(1).optional(),
});

export type AddCartItemBody = z.infer<typeof addCartItemBodySchema>;

// ---------------------------------------------------------------------------
// PATCH /api/cart/items/[dealSkuId]   — update qty
// ---------------------------------------------------------------------------

export const updateCartItemBodySchema = z.object({
  qty: qtySchema,
  csrfToken: z.string().min(1).optional(),
});

export type UpdateCartItemBody = z.infer<typeof updateCartItemBodySchema>;

// ---------------------------------------------------------------------------
// DELETE /api/cart/items/[dealSkuId]   — no body needed (dealSkuId from path)
// Body schema for CSRF token if sent in body
// ---------------------------------------------------------------------------

export const deleteCartItemBodySchema = z
  .object({
    csrfToken: z.string().min(1).optional(),
  })
  .optional();

export type DeleteCartItemBody = z.infer<typeof deleteCartItemBodySchema>;

// ---------------------------------------------------------------------------
// POST /api/cart/merge   — merge anonymous cart on login
// ---------------------------------------------------------------------------

export const mergeCartBodySchema = z.object({
  items: z
    .array(
      z.object({
        dealSkuId: uuidSchema,
        qty: qtySchema,
      }),
    )
    .max(50, 'Cart cannot exceed 50 distinct SKUs'),
  csrfToken: z.string().min(1).optional(),
});

export type MergeCartBody = z.infer<typeof mergeCartBodySchema>;

// ---------------------------------------------------------------------------
// POST /api/cart/checkout   — single multi-line checkout transaction
// ---------------------------------------------------------------------------

export const checkoutBodySchema = z.object({
  paymentMethodId: uuidSchema.optional(),
  csrfToken: z.string().min(1).optional(),
  promoCode: z.string().min(1).max(64).optional(),
  /** When true, skip auto-applying referral credit for this order. */
  holdCredit: z.boolean().optional(),
});

export type CheckoutBody = z.infer<typeof checkoutBodySchema>;

// ---------------------------------------------------------------------------
// Response types (used by client for type inference)
// ---------------------------------------------------------------------------

export const cartLineItemSchema = z.object({
  cartItemId: uuidSchema,
  dealId: uuidSchema,
  dealSkuId: uuidSchema.nullable(),
  /** Locale-aware SKU label, e.g. "L · Red". Null for deals without variants. */
  skuLabel: z.string().nullable(),
  qty: z.int().min(0),
  addedAt: z.iso.datetime(),
  dealTitle: z.string(),
  vendorId: uuidSchema,
  vendorName: z.string(),
  discountedPrice: z.string(),
  originalPrice: z.string(),
  commissionRate: z.string(),
  maxPerUser: z.int().nullable(),
  remainingStock: z.int().min(0),
  dealState: z.string(),
  windowEnd: z.iso.datetime().nullable(),
});

export type CartLineItem = z.infer<typeof cartLineItemSchema>;

export const staleEntrySchema = z.object({
  dealId: uuidSchema,
  reason: z.enum(['expired', 'inactive', 'sold_out']),
});

export type StaleEntry = z.infer<typeof staleEntrySchema>;

export const cartResponseSchema = z.object({
  ok: z.literal(true),
  items: z.array(cartLineItemSchema),
  removed: z.array(staleEntrySchema),
  subtotal: z.string(),
});

export type CartResponse = z.infer<typeof cartResponseSchema>;

export const checkoutResultSchema = z.object({
  ok: z.literal(true),
  purchaseIds: z.array(uuidSchema),
});

export type CheckoutResult = z.infer<typeof checkoutResultSchema>;
