/**
 * Memberships Domain - Zod Validation Schemas
 *
 * Validation schemas for membership management endpoints.
 * Includes request bodies, query params, and path params.
 *
 * Security:
 * - All schemas use .strict() to prevent mass assignment attacks
 * - UUID validation prevents invalid references
 * - Role enum validation prevents privilege escalation
 * - organizationId never accepted in body (from JWT when needed)
 */

import { z } from 'zod'

// ============================================================================
// Shared Schemas
// ============================================================================

/**
 * Membership role validation
 * Accepts any non-empty role slug (max 64 chars).
 *
 * Roles are now DB-driven via `org_rol_definitions`. Runtime validation
 * against valid slugs happens at the service layer, not here.
 */
export const MembershipRoleSchema = z.string().min(1).max(64)

/**
 * Membership status validation
 * Note: Database constraint only allows 'active' | 'inactive'
 */
export const MembershipStatusSchema = z.enum(['active', 'inactive'])

// ============================================================================
// Path Parameters
// ============================================================================

/**
 * Validate membership ID in URL path
 * Used by: GET/PUT/DELETE /memberships/:id
 */
export const MembershipIdParamSchema = z
  .object({
    id: z.string().min(1) // WorkOS membership IDs can be various formats
  })
  .strict()

/**
 * Validate organization ID (Supabase UUID) in URL path
 * Used by: GET /memberships/my-permissions/:orgId
 */
export const OrgIdParamSchema = z
  .object({
    orgId: z.string().uuid()
  })
  .strict()

/**
 * Response shape for GET /memberships/my-permissions/:orgId
 */
export const MyOrgPermissionsResponseSchema = z.object({
  permissions: z.array(z.string())
})

// ============================================================================
// Request Bodies
// ============================================================================

/**
 * Create new membership
 * POST /memberships
 *
 * Security:
 * - userId must be valid (string format for WorkOS)
 * - organizationId must be valid (string format for WorkOS)
 * - roleSlug validated as non-empty slug; service layer checks against org_rol_definitions
 * - Strict mode prevents injection
 */
export const CreateMembershipSchema = z
  .object({
    userId: z.string().min(1),
    organizationId: z.string().min(1),
    roleSlug: MembershipRoleSchema.default('member')
  })
  .strict()

/**
 * Update membership role
 * PUT /memberships/:id
 *
 * Security:
 * - Only roleSlug can be updated
 * - Service layer validates slug against org_rol_definitions
 */
export const UpdateMembershipSchema = z
  .object({
    roleSlug: MembershipRoleSchema
  })
  .strict()

// ============================================================================
// Query Parameters
// ============================================================================

/**
 * List memberships with filters
 * GET /memberships
 *
 * Filters:
 * - userId: Filter by user
 * - organizationId: Filter by organization
 *
 * Security:
 * - Requires at least one filter parameter
 * - String IDs validated for WorkOS format
 */
export const ListMembershipsQuerySchema = z
  .object({
    userId: z.string().optional(),
    organizationId: z.string().optional(),
    limit: z.coerce.number().int().min(1).max(100).optional(),
    before: z.string().optional(), // WorkOS pagination cursor
    after: z.string().optional() // WorkOS pagination cursor
  })
  .strict()
  .refine((data) => data.userId || data.organizationId, {
    message: 'Either userId or organizationId must be provided'
  })

// ============================================================================
// TypeScript Type Exports
// ============================================================================

// Export inferred types for use in route handlers
export type CreateMembershipInput = z.infer<typeof CreateMembershipSchema>
export type UpdateMembershipInput = z.infer<typeof UpdateMembershipSchema>
export type ListMembershipsQuery = z.infer<typeof ListMembershipsQuerySchema>
export type MembershipIdParam = z.infer<typeof MembershipIdParamSchema>
export type MembershipRole = z.infer<typeof MembershipRoleSchema>
export type MembershipStatus = z.infer<typeof MembershipStatusSchema>
export type OrgIdParam = z.infer<typeof OrgIdParamSchema>
export type MyOrgPermissionsResponse = z.infer<typeof MyOrgPermissionsResponseSchema>
