/**
 * Invitations Domain - Zod Validation Schemas
 *
 * Validation schemas for invitation management endpoints.
 * Includes request bodies, query params, and path params.
 *
 * Security:
 * - All schemas use .strict() to prevent mass assignment attacks
 * - Email validation prevents header injection
 * - Role enum validation prevents privilege escalation
 * - organizationId from JWT (not accepted in body for protected routes)
 */

import { z } from 'zod'
import { EmailSchema } from '../../../platform/utils/validation'
import { MembershipRoleSchema } from '../memberships/api-schemas'

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

/**
 * Validate invitation ID in URL path
 * Used by: GET/DELETE /invitations/:id
 */
export const InvitationIdParamSchema = z
  .object({
    id: z.string().min(1) // WorkOS invitation IDs
  })
  .strict()

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

/**
 * Send new invitation
 * POST /invitations
 *
 * Security:
 * - Email format validated (prevents header injection)
 * - roleSlug validated as non-empty slug; service layer checks against org_rol_definitions
 * - expiresInDays bounded (1-90 days)
 * - organizationId NOT in body (from JWT via requireOrganization middleware)
 */
export const SendInvitationSchema = z
  .object({
    email: EmailSchema,
    organizationId: z.string().optional(), // For WorkOS API - but typically from JWT
    roleSlug: MembershipRoleSchema.default('member'),
    expiresInDays: z.number().int().min(1).max(90).default(7)
  })
  .strict()

/**
 * Accept invitation by token
 * POST /invitations/accept
 *
 * Security:
 * - Token validated (non-empty string)
 */
export const AcceptInvitationSchema = z
  .object({
    invitation_token: z.string().min(1, 'Invitation token is required')
  })
  .strict()

/**
 * Public invitation router query
 * GET /api/invite
 *
 * Security:
 * - Token validated as present only; service layer performs WorkOS lookup
 * - Router redirects with only the token needed by tenant AuthKit login
 */
export const InviteRouterQuerySchema = z
  .object({
    invitation_token: z.string().min(1, 'Invitation token is required')
  })
  .strict()

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

/**
 * List invitations with filters
 * GET /invitations
 *
 * Filters:
 * - organizationId: Filter by organization
 * - email: Filter by email
 *
 * Security:
 * - Requires organizationId or userId filter
 * - Email validated
 */
export const ListInvitationsQuerySchema = z
  .object({
    organizationId: z.string().optional(),
    userId: z.string().optional(),
    email: EmailSchema.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.organizationId || data.userId, { message: 'Either organizationId or userId must be provided' })

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

// Export inferred types for use in route handlers
export type SendInvitationInput = z.infer<typeof SendInvitationSchema>
export type AcceptInvitationInput = z.infer<typeof AcceptInvitationSchema>
export type InviteRouterQuery = z.infer<typeof InviteRouterQuerySchema>
export type ListInvitationsQuery = z.infer<typeof ListInvitationsQuerySchema>
export type InvitationIdParam = z.infer<typeof InvitationIdParamSchema>
