/**
 * Waitlist types — pre-launch signup collection.
 *
 * Cosmos container: `waitlist` (partition key: `/email`)
 * Product-agnostic: every document includes `productId`.
 */

import { z } from 'zod';

// ── Waitlist entry document ──

export interface WaitlistEntryDoc {
  id: string;
  productId: string;
  email: string;
  emailNormalized: string;
  name?: string;
  source: 'organic' | 'referral' | 'social' | 'ad' | 'api';
  referredBy?: string;
  status: 'pending' | 'invited' | 'converted' | 'unsubscribed';
  position: number;
  priority: number;
  customData: Record<string, unknown>;
  invitationCodeId?: string;
  invitedAt?: string;
  convertedAt?: string;
  ipHash?: string;
  utmSource?: string;
  utmMedium?: string;
  utmCampaign?: string;
  unsubscribeToken: string;
  createdAt: string;
  updatedAt: string;
}

export const WAITLIST_STATUSES = ['pending', 'invited', 'converted', 'unsubscribed'] as const;
export type WaitlistStatus = (typeof WAITLIST_STATUSES)[number];

export const WAITLIST_SOURCES = ['organic', 'referral', 'social', 'ad', 'api'] as const;
export type WaitlistSource = (typeof WAITLIST_SOURCES)[number];

// ── Public schemas ──

export const JoinWaitlistSchema = z.object({
  email: z.string().email().max(320),
  name: z.string().max(128).optional(),
  source: z.enum(WAITLIST_SOURCES).default('organic'),
  ref: z.string().max(128).optional(),
  customData: z.record(z.unknown()).default({}),
  captchaToken: z.string().max(4096).optional(),
  utmSource: z.string().max(256).optional(),
  utmMedium: z.string().max(256).optional(),
  utmCampaign: z.string().max(256).optional(),
});

export const CheckStatusSchema = z.object({
  email: z.string().email(),
  unsubscribeToken: z.string().min(1),
});

export const UnsubscribeSchema = z.object({
  email: z.string().email(),
  unsubscribeToken: z.string().min(1),
});

// ── Admin schemas ──

export const UpdateWaitlistEntrySchema = z.object({
  status: z.enum(WAITLIST_STATUSES).optional(),
  priority: z.number().int().min(0).optional(),
  name: z.string().max(128).optional(),
});

export const WaitlistQuerySchema = z.object({
  productId: z.string().optional(),
  status: z.enum(WAITLIST_STATUSES).optional(),
  source: z.enum(WAITLIST_SOURCES).optional(),
  q: z.string().max(256).optional(),
  sortBy: z.enum(['position', 'priority', 'createdAt']).default('position'),
  sortOrder: z.enum(['asc', 'desc']).default('asc'),
  limit: z.coerce.number().int().min(1).max(500).default(50),
  offset: z.coerce.number().int().min(0).default(0),
});

export const BatchInviteSchema = z.object({
  count: z.number().int().min(1).max(500),
  strategy: z.enum(['fifo', 'priority', 'random']).default('fifo'),
});

// ── Inferred types ──

export type JoinWaitlistInput = z.infer<typeof JoinWaitlistSchema>;
export type CheckStatusInput = z.infer<typeof CheckStatusSchema>;
export type UnsubscribeInput = z.infer<typeof UnsubscribeSchema>;
export type UpdateWaitlistEntryInput = z.infer<typeof UpdateWaitlistEntrySchema>;
export type WaitlistQueryInput = z.infer<typeof WaitlistQuerySchema>;
export type BatchInviteInput = z.infer<typeof BatchInviteSchema>;
