import {
  IsArray,
  IsBoolean,
  IsIn,
  IsObject,
  IsOptional,
  IsString,
  IsUUID,
  MaxLength,
} from 'class-validator';

const agentStatuses = ['idle', 'active', 'error', 'offline'] as const;

// ─── Agent Capability Declarations (M4-011) ───────────────────────────────────

/**
 * Agent specialization capability fields.
 * Stored inside the agent's `config` JSON as `capabilities`.
 */
export class AgentCapabilitiesDto {
  /**
   * Domains this agent specializes in, e.g. ['frontend', 'backend', 'devops'].
   * Used by the routing engine to bias toward this agent for matching domains.
   */
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  domains?: string[];

  /**
   * Default model identifier for this agent.
   * Influences routing when no explicit rule overrides the choice.
   */
  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredModel?: string;

  /**
   * Default provider for this agent.
   * Influences routing when no explicit rule overrides the choice.
   */
  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredProvider?: string;

  /**
   * Tool categories this agent has access to, e.g. ['web-search', 'code-exec'].
   */
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  toolSets?: string[];
}

// ─── Create DTO ───────────────────────────────────────────────────────────────

export class CreateAgentConfigDto {
  @IsString()
  @MaxLength(255)
  name!: string;

  @IsString()
  @MaxLength(255)
  provider!: string;

  @IsString()
  @MaxLength(255)
  model!: string;

  @IsOptional()
  @IsIn(agentStatuses)
  status?: 'idle' | 'active' | 'error' | 'offline';

  @IsOptional()
  @IsUUID()
  projectId?: string;

  @IsOptional()
  @IsString()
  @MaxLength(50_000)
  systemPrompt?: string;

  @IsOptional()
  @IsArray()
  allowedTools?: string[];

  @IsOptional()
  @IsArray()
  skills?: string[];

  @IsOptional()
  @IsBoolean()
  isSystem?: boolean;

  /**
   * General config blob. May include `capabilities` (AgentCapabilitiesDto)
   * for agent specialization declarations (M4-011).
   */
  @IsOptional()
  @IsObject()
  config?: Record<string, unknown>;

  // ─── Capability shorthand fields (M4-011) ──────────────────────────────────
  // These are convenience top-level fields that get merged into config.capabilities.

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  domains?: string[];

  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredModel?: string;

  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredProvider?: string;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  toolSets?: string[];
}

// ─── Update DTO ───────────────────────────────────────────────────────────────

export class UpdateAgentConfigDto {
  @IsOptional()
  @IsString()
  @MaxLength(255)
  name?: string;

  @IsOptional()
  @IsString()
  @MaxLength(255)
  provider?: string;

  @IsOptional()
  @IsString()
  @MaxLength(255)
  model?: string;

  @IsOptional()
  @IsIn(agentStatuses)
  status?: 'idle' | 'active' | 'error' | 'offline';

  @IsOptional()
  @IsUUID()
  projectId?: string | null;

  @IsOptional()
  @IsString()
  @MaxLength(50_000)
  systemPrompt?: string | null;

  @IsOptional()
  @IsArray()
  allowedTools?: string[] | null;

  @IsOptional()
  @IsArray()
  skills?: string[] | null;

  /**
   * General config blob. May include `capabilities` (AgentCapabilitiesDto)
   * for agent specialization declarations (M4-011).
   */
  @IsOptional()
  @IsObject()
  config?: Record<string, unknown> | null;

  // ─── Capability shorthand fields (M4-011) ──────────────────────────────────

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  domains?: string[] | null;

  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredModel?: string | null;

  @IsOptional()
  @IsString()
  @MaxLength(255)
  preferredProvider?: string | null;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  toolSets?: string[] | null;
}
