import { z } from 'zod'
import type { ActionConfig } from './types'
import { FormFieldSchema, FormSchemaSchema } from '../../forms/schemas'

/**
 * Zod validation schemas for HITL types
 * Provides runtime validation for action configs and task creation
 * Note: Form validation schemas are imported from shared forms module
 */

/**
 * Action configuration schema validation
 */
export const ActionConfigSchema = z.object({
  id: z
    .string()
    .min(1, 'Action ID is required')
    .regex(/^[a-z0-9-]+$/, 'Action ID must be lowercase alphanumeric with hyphens'),
  label: z.string().min(1, 'Action label is required'),
  type: z.enum(['primary', 'secondary', 'danger', 'outline']),
  icon: z.string().optional(),
  color: z.string().optional(),
  variant: z.string().optional(),
  target: z
    .object({
      resourceType: z.enum(['agent', 'workflow']),
      resourceId: z.string().min(1, 'Resource ID is required')
    })
    .optional(),
  form: FormSchemaSchema.optional(),
  payloadTemplate: z.unknown().optional(),
  requiresConfirmation: z.boolean().optional(),
  confirmationMessage: z.string().optional(),
  description: z.string().optional()
})

/**
 * Create task parameters schema validation
 */
export const CreateTaskParamsSchema = z.object({
  organizationId: z.string().uuid('Organization ID must be a valid UUID'),
  originExecutionId: z.string().min(1, 'Origin execution ID is required'),
  originResourceType: z.string().min(1, 'Origin resource type is required'),
  originResourceId: z.string().min(1, 'Origin resource ID is required'),
  actions: z.array(ActionConfigSchema).min(1, 'At least one action is required').max(20, 'Maximum 20 actions allowed'),
  context: z.unknown().refine((val) => val !== null && val !== undefined, { message: 'Context is required' }),
  description: z.string().optional(),
  priority: z
    .number()
    .int('Priority must be an integer')
    .min(1, 'Priority must be at least 1')
    .max(10, 'Priority must be at most 10')
    .optional(),
  expiresAt: z.date().optional(),
  idempotencyKey: z.string().min(1).max(255).optional()
})

/**
 * Submit action parameters schema validation
 */
export const SubmitActionParamsSchema = z.object({
  actionId: z.string().min(1, 'Action ID is required'),
  payload: z.unknown().optional(),
  notes: z.string().optional(),
  userId: z.string().min(1, 'User ID is required')
})

/**
 * Validates an array of action configs
 * Checks bounds, per-item schema, and duplicate IDs
 * @throws ZodError if validation fails
 * @throws Error if duplicate action IDs are found
 */
export function validateActions(actions: unknown): ActionConfig[] {
  const validated = z
    .array(ActionConfigSchema)
    .min(1, 'At least one action is required')
    .max(20, 'Maximum 20 actions allowed')
    .parse(actions)

  // Check for duplicate IDs
  const ids = new Set<string>()
  for (const action of validated) {
    if (ids.has(action.id)) {
      throw new Error(`Duplicate action id: ${action.id}`)
    }
    ids.add(action.id)
  }

  return validated
}

/**
 * Validates a single action config
 * @throws ZodError if validation fails
 */
export function validateActionConfig(action: unknown): ActionConfig {
  return ActionConfigSchema.parse(action)
}

/**
 * Patch task parameters schema validation
 * All fields optional, but at least one must be provided
 */
export const PatchTaskRequestSchema = z
  .object({
    humanCheckpoint: z.string().min(1).nullable().optional(),
    description: z.string().min(1).optional(),
    priority: z.number().int().min(1).max(10).optional(),
    context: z.record(z.string(), z.unknown()).optional(),
    actions: z.array(z.unknown()).optional()
  })
  .refine((data) => Object.keys(data).length > 0, {
    message: 'At least one field must be provided'
  })

/**
 * Re-export form validation schemas for backwards compatibility
 */
export { FormFieldSchema, FormSchemaSchema }

/**
 * Re-export form validation functions for backwards compatibility
 */
export { validateFormSchema, validateFormField } from '../../forms/schemas'
