/**
 * Feed filter schema — shared between server (API routes, query layer) and client.
 *
 * Keep import-free of server-only modules so it can be used in React islands
 * without bundling CF Worker bindings.
 */
import { z } from 'zod';
import { dealTypeSchema } from '@/lib/deal-types/schema';

export const feedFilterSchema = z.object({
  cityCode: z.string().max(64).optional(),
  radius: z
    .object({
      lat: z.number(),
      lng: z.number(),
      km: z.number().int().min(1).max(50),
    })
    .optional(),
  dealType: dealTypeSchema.optional(),
  categoryId: z.uuid().optional(),
  tagIds: z.array(z.uuid()).max(10).optional(),
  /** Min discounted price (shekels). Omit when slider at domain floor. */
  minPrice: z.number().int().min(0).max(100000).optional(),
  /** Max discounted price (shekels). Omit when slider at domain ceiling (whales reachable). */
  maxPrice: z.number().int().min(0).max(100000).optional(),
  hours: z
    .discriminatedUnion('mode', [
      z.object({ mode: z.literal('any') }),
      z.object({ mode: z.literal('openNow') }),
      z.object({
        mode: z.literal('window'),
        /** 0 = Sunday … 6 = Saturday (matches JS Date.getDay()) */
        dayOfWeek: z.number().int().min(0).max(6),
        /** Minutes from midnight (0–1439) */
        startMin: z.number().int().min(0).max(1439),
        /** Minutes from midnight (0–1439). May be < startMin for midnight-spanning windows. */
        endMin: z.number().int().min(0).max(1439),
      }),
    ])
    .default({ mode: 'any' }),
  cursor: z.string().optional(),
  limit: z.number().int().min(1).max(50).default(20),
  page: z.number().int().min(1).optional(), // offset-based; when set, cursor is ignored
  preset: z.enum(['near-you', 'all']).optional(),
});

export type FeedFilter = z.infer<typeof feedFilterSchema>;
