/**
 * A/B Testing (Experiments) module — types and schemas.
 * Deterministic variant assignment via FNV-1a hash (same as feature flags).
 */

import { z } from 'zod';

export type ExperimentStatus = 'draft' | 'running' | 'paused' | 'completed';

export interface ExperimentVariant {
  key: string; // e.g. 'control', 'variant_a', 'variant_b'
  weight: number; // 0–100, must sum to 100
  description: string;
}

export interface ExperimentDoc {
  id: string;
  productId: string;
  key: string; // unique slug: 'onboarding_flow_v2'
  name: string;
  description: string;
  status: ExperimentStatus;
  variants: ExperimentVariant[];
  targetSegments: string[]; // optional user segments
  trafficPercent: number; // 0–100 — % of eligible users enrolled
  startedAt: string | null;
  endedAt: string | null;
  createdAt: string;
  updatedAt: string;
}

export interface ExperimentAssignmentDoc {
  id: string; // `${experimentId}:${userId}`
  productId: string;
  experimentId: string;
  userId: string;
  variantKey: string;
  assignedAt: string;
}

// ── Schemas ────────────────────────────────────────────────────

const VariantSchema = z.object({
  key: z
    .string()
    .min(1)
    .regex(/^[a-z0-9_]+$/),
  weight: z.number().int().min(0).max(100),
  description: z.string().default(''),
});

export const CreateExperimentSchema = z
  .object({
    key: z
      .string()
      .min(1)
      .regex(/^[a-z0-9_]+$/),
    name: z.string().min(1).max(200),
    description: z.string().default(''),
    variants: z.array(VariantSchema).min(2).max(10),
    targetSegments: z.array(z.string()).default([]),
    trafficPercent: z.number().int().min(1).max(100).default(100),
  })
  .refine(d => d.variants.reduce((s, v) => s + v.weight, 0) === 100, {
    message: 'Variant weights must sum to 100',
    path: ['variants'],
  });

export const UpdateExperimentSchema = z.object({
  name: z.string().min(1).max(200).optional(),
  description: z.string().optional(),
  status: z.enum(['draft', 'running', 'paused', 'completed']).optional(),
  targetSegments: z.array(z.string()).optional(),
  trafficPercent: z.number().int().min(1).max(100).optional(),
});

export type CreateExperimentInput = z.infer<typeof CreateExperimentSchema>;
export type UpdateExperimentInput = z.infer<typeof UpdateExperimentSchema>;
