/**
 * Organizations Domain - Zod Validation Schemas
 *
 * Validation schemas for organization management endpoints.
 * Includes request bodies, query params, and path params.
 *
 * Security:
 * - All schemas use .strict() to prevent mass assignment attacks
 * - UUID/WorkOS ID validation prevents invalid references
 * - String length limits prevent DoS
 * - Domain and metadata size limits
 */

import { z } from 'zod'
import { UuidSchema } from '../../../platform/utils/validation'

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

/**
 * Organization name validation
 * - Alphanumeric, spaces, hyphens, underscores only
 * - 2-100 characters
 *
 * Security: Prevents injection, DoS via long names
 */
export const OrganizationNameSchema = z
  .string()
  .min(2, 'Organization name must be at least 2 characters')
  .max(100, 'Organization name must be at most 100 characters')
  .trim()
  .regex(
    /^[a-zA-Z0-9\s\-_]+$/,
    'Organization name must contain only letters, numbers, spaces, hyphens, and underscores'
  )

/**
 * Organization ID validation
 * Supports both UUID and WorkOS org_ prefixed IDs
 */
export const OrganizationIdSchema = z.union([
  UuidSchema,
  z.string().regex(/^org_[a-zA-Z0-9]+$/, 'Invalid WorkOS organization ID')
])

/**
 * Organization domain data schema
 */
export const OrganizationDomainSchema = z.object({
  domain: z.string().min(3).max(255),
  state: z.enum(['verified', 'pending', 'failed']).optional()
})

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

/**
 * Validate organization ID in URL path
 * Used by: GET/PUT/DELETE /organizations/:id
 */
export const OrganizationIdParamSchema = z
  .object({
    id: OrganizationIdSchema
  })
  .strict()

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

/**
 * Create new organization
 * POST /organizations
 *
 * Security:
 * - Name format validated (alphanumeric + spaces + hyphens + underscores)
 * - Domain array size limited (max 10)
 * - Metadata size limited (10KB)
 * - Strict mode prevents unknown field injection
 */
export const CreateOrganizationSchema = z
  .object({
    name: OrganizationNameSchema,
    domainData: z.array(OrganizationDomainSchema).max(10).optional(),
    metadata: z
      .record(z.string(), z.unknown())
      .refine((val) => JSON.stringify(val).length <= 10240, 'Metadata must be under 10KB')
      .optional()
  })
  .strict()

/**
 * Update organization
 * PUT /organizations/:id
 *
 * Security:
 * - All fields optional (partial update)
 * - Same validation as create
 * - At least one field required (matches documented Update schema convention,
 *   see .claude/rules/core-package.md → "api-schemas.ts Pattern")
 */
export const UpdateOrganizationSchema = CreateOrganizationSchema.partial()
  .strict()
  .refine((data) => Object.keys(data).length > 0, {
    message: 'At least one field (name, domainData, or metadata) must be provided'
  })

/**
 * Update organization auth config
 * PATCH /organizations/:id/config/auth
 *
 * Security:
 * - Narrow config surface: only appOrigin is accepted
 * - App origin is an origin URL, not a route URL
 * - Strict mode prevents accidental writes to unrelated config keys
 */
export const UpdateOrganizationAuthConfigSchema = z
  .object({
    appOrigin: z
      .string()
      .trim()
      .url('App origin must be a valid URL')
      .max(2048, 'App origin must be at most 2048 characters')
      .refine((value) => {
        try {
          const url = new URL(value)
          return url.pathname === '/' && url.search === '' && url.hash === ''
        } catch {
          return false
        }
      }, 'App origin must not include a path, query string, or hash')
  })
  .strict()

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

/**
 * List organizations with filters
 * GET /organizations
 *
 * Security:
 * - Limit bounded (prevents DoS)
 * - WorkOS pagination cursors
 */
export const ListOrganizationsQuerySchema = z.object({
  limit: z.coerce.number().int().min(1).max(100).default(20),
  before: z.string().optional(), // WorkOS pagination cursor
  after: z.string().optional() // WorkOS pagination cursor
})

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

// Export inferred types for use in route handlers
export type CreateOrganizationInput = z.infer<typeof CreateOrganizationSchema>
export type UpdateOrganizationInput = z.infer<typeof UpdateOrganizationSchema>
export type UpdateOrganizationAuthConfigInput = z.infer<typeof UpdateOrganizationAuthConfigSchema>
export type ListOrganizationsQuery = z.infer<typeof ListOrganizationsQuerySchema>
export type OrganizationIdParam = z.infer<typeof OrganizationIdParamSchema>
