/**
 * API Versioning module — types and schemas.
 * Manages API version lifecycle, deprecation notices, migration guides,
 * and per-client version pinning.
 */

import { z } from 'zod';

// ── API Version Types ────────────────────────────────────────────

export type VersionStatus = 'draft' | 'active' | 'deprecated' | 'sunset';

export interface ApiVersionDoc {
  id: string;
  productId: string;
  /** Version string (e.g. "v1", "v2", "2024-01-15") */
  version: string;
  status: VersionStatus;
  /** Human-readable label */
  label: string;
  /** Release date */
  releasedAt: string | null;
  /** Deprecation date (when deprecated notice starts) */
  deprecatedAt: string | null;
  /** Sunset date (when version is removed) */
  sunsetAt: string | null;
  /** Migration guide URL or inline markdown */
  migrationGuide: string | null;
  /** Breaking changes summary */
  breakingChanges: string[];
  /** Endpoints added in this version */
  addedEndpoints: string[];
  /** Endpoints removed in this version */
  removedEndpoints: string[];
  /** Endpoints modified in this version */
  modifiedEndpoints: string[];
  createdAt: string;
  updatedAt: string;
  updatedBy: string;
}

export interface ClientVersionPinDoc {
  id: string;
  productId: string;
  /** Client identifier (API key ID, app ID, or user ID) */
  clientId: string;
  /** Pinned version */
  pinnedVersion: string;
  /** Why the client is pinned (e.g. "Legacy integration") */
  reason: string;
  /** Auto-upgrade after this date */
  autoUpgradeAt: string | null;
  createdAt: string;
  updatedAt: string;
  updatedBy: string;
}

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

export const CreateApiVersionSchema = z.object({
  version: z
    .string()
    .min(1)
    .max(32)
    .regex(/^[a-zA-Z0-9._-]+$/, 'Version must be alphanumeric with dots, hyphens, underscores'),
  label: z.string().min(1).max(200),
  status: z.enum(['draft', 'active', 'deprecated', 'sunset']).default('draft'),
  releasedAt: z.string().datetime().nullable().optional(),
  migrationGuide: z.string().max(5000).nullable().optional(),
  breakingChanges: z.array(z.string().max(500)).max(50).default([]),
  addedEndpoints: z.array(z.string().max(200)).max(100).default([]),
  removedEndpoints: z.array(z.string().max(200)).max(100).default([]),
  modifiedEndpoints: z.array(z.string().max(200)).max(100).default([]),
});

export const UpdateApiVersionSchema = z.object({
  label: z.string().min(1).max(200).optional(),
  status: z.enum(['draft', 'active', 'deprecated', 'sunset']).optional(),
  releasedAt: z.string().datetime().nullable().optional(),
  deprecatedAt: z.string().datetime().nullable().optional(),
  sunsetAt: z.string().datetime().nullable().optional(),
  migrationGuide: z.string().max(5000).nullable().optional(),
  breakingChanges: z.array(z.string().max(500)).max(50).optional(),
  addedEndpoints: z.array(z.string().max(200)).max(100).optional(),
  removedEndpoints: z.array(z.string().max(200)).max(100).optional(),
  modifiedEndpoints: z.array(z.string().max(200)).max(100).optional(),
});

export const PinClientVersionSchema = z.object({
  clientId: z.string().min(1).max(128),
  pinnedVersion: z.string().min(1).max(32),
  reason: z.string().min(1).max(500),
  autoUpgradeAt: z.string().datetime().nullable().optional(),
});

export const UpdateClientPinSchema = z.object({
  pinnedVersion: z.string().min(1).max(32).optional(),
  reason: z.string().min(1).max(500).optional(),
  autoUpgradeAt: z.string().datetime().nullable().optional(),
});

export type CreateApiVersionInput = z.infer<typeof CreateApiVersionSchema>;
export type UpdateApiVersionInput = z.infer<typeof UpdateApiVersionSchema>;
export type PinClientVersionInput = z.infer<typeof PinClientVersionSchema>;
export type UpdateClientPinInput = z.infer<typeof UpdateClientPinSchema>;
