import { z } from "zod";

/** Comma-separated query params arrive as one string; split them into a list. */
const csv = z
  .string()
  .optional()
  .transform((v) =>
    v
      ? v
          .split(",")
          .map((s) => s.trim())
          .filter(Boolean)
      : undefined,
  );

export const EventFiltersSchema = z.object({
  /** Inclusive lower bound on the event timestamp (ISO or yyyy-mm-dd). */
  from: z.string().optional(),
  /** Inclusive upper bound. A date-only value is widened to end-of-day. */
  to: z.string().optional(),
  /** Collection names, e.g. "add_to_cart,purchase". Empty means all of them. */
  eventTypes: csv,
  memberId: z.string().optional(),
  currency: z.string().optional(),
  /** Exact property name, e.g. "Karma Chakra". */
  property: z.string().optional(),
  /** Exact `sourceOfEvent` value, e.g. "properties". */
  source: z.string().optional(),
  /** Free text over member id, property, experience, offer, source and event type. */
  search: z.string().optional(),
});

export type EventFiltersInput = z.infer<typeof EventFiltersSchema>;

export const PaginationSchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  pageSize: z.coerce.number().int().min(1).max(200).default(25),
  /** Opaque cursor from a previous page; skips the offset scan when supplied. */
  cursor: z.string().optional(),
});

export const ListEventsSchema = EventFiltersSchema.merge(PaginationSchema);
export const MemberAnalyticsSchema = EventFiltersSchema.merge(
  z.object({
    page: z.coerce.number().int().min(1).default(1),
    pageSize: z.coerce.number().int().min(1).max(200).default(25),
    sortBy: z
      .enum(["events", "revenue", "points", "lastSeen", "member"])
      .default("events"),
    /**
     * Free text over member number, name and email.
     *
     * Separate from the page-wide `search`: this narrows the member list only,
     * leaving the summary tiles and the other tabs reporting on the full filter.
     * It is applied to the whole member set before paging, so it finds members
     * who are not on the current page.
     */
    memberSearch: z.string().optional(),
    sortDir: z.enum(["asc", "desc"]).default("desc"),
  }),
);
