import {
  IsString,
  IsOptional,
  IsBoolean,
  IsNumber,
  IsArray,
  IsObject,
  IsUUID,
  MaxLength,
  MinLength,
  Min,
  Max,
} from 'class-validator';

// ============================================
// PROMPT DTOs
// ============================================

export class CreatePromptDto {
  @IsString()
  @MinLength(2)
  @MaxLength(50)
  code: string;

  @IsString()
  @MinLength(2)
  @MaxLength(100)
  name: string;

  @IsOptional()
  @IsString()
  description?: string;

  @IsOptional()
  @IsString()
  @MaxLength(30)
  category?: string;

  @IsString()
  systemPrompt: string;

  @IsOptional()
  @IsString()
  userPromptTemplate?: string;

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

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  temperature?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  maxTokens?: number;

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

  @IsOptional()
  @IsObject()
  modelParameters?: Record<string, any>;

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

  @IsOptional()
  @IsObject()
  metadata?: Record<string, any>;
}

export class UpdatePromptDto {
  @IsOptional()
  @IsString()
  @MaxLength(100)
  name?: string;

  @IsOptional()
  @IsString()
  description?: string;

  @IsOptional()
  @IsString()
  @MaxLength(30)
  category?: string;

  @IsOptional()
  @IsString()
  systemPrompt?: string;

  @IsOptional()
  @IsString()
  userPromptTemplate?: string;

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

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  temperature?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  maxTokens?: number;

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

  @IsOptional()
  @IsObject()
  modelParameters?: Record<string, any>;

  @IsOptional()
  @IsBoolean()
  isActive?: boolean;
}

// ============================================
// CONVERSATION DTOs
// ============================================

export class CreateConversationDto {
  @IsOptional()
  @IsUUID()
  modelId?: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(200)
  title?: string;

  @IsOptional()
  @IsString()
  systemPrompt?: string;

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  temperature?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  maxTokens?: number;

  @IsOptional()
  @IsObject()
  context?: Record<string, any>;

  @IsOptional()
  @IsObject()
  metadata?: Record<string, any>;
}

export class UpdateConversationDto {
  @IsOptional()
  @IsString()
  @MaxLength(200)
  title?: string;

  @IsOptional()
  @IsString()
  systemPrompt?: string;

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  temperature?: number;

  @IsOptional()
  @IsNumber()
  @Min(1)
  maxTokens?: number;

  @IsOptional()
  @IsObject()
  context?: Record<string, any>;

  @IsOptional()
  @IsObject()
  metadata?: Record<string, any>;
}

// ============================================
// MESSAGE DTOs
// ============================================

export class AddMessageDto {
  @IsString()
  @MaxLength(20)
  role: string;

  @IsString()
  content: string;

  @IsOptional()
  @IsString()
  @MaxLength(50)
  modelCode?: string;

  @IsOptional()
  @IsNumber()
  @Min(0)
  promptTokens?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  completionTokens?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  totalTokens?: number;

  @IsOptional()
  @IsString()
  @MaxLength(30)
  finishReason?: string;

  @IsOptional()
  @IsNumber()
  @Min(0)
  latencyMs?: number;

  @IsOptional()
  @IsObject()
  metadata?: Record<string, any>;
}

// ============================================
// USAGE DTOs
// ============================================

export class LogUsageDto {
  @IsOptional()
  @IsUUID()
  userId?: string;

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

  @IsUUID()
  modelId: string;

  @IsString()
  @MaxLength(20)
  usageType: string;

  @IsNumber()
  @Min(0)
  inputTokens: number;

  @IsNumber()
  @Min(0)
  outputTokens: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  costUsd?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  latencyMs?: number;

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

  @IsOptional()
  @IsString()
  errorMessage?: string;

  @IsOptional()
  @IsObject()
  metadata?: Record<string, any>;
}

// ============================================
// QUOTA DTOs
// ============================================

export class UpdateQuotaDto {
  @IsOptional()
  @IsNumber()
  @Min(0)
  maxRequestsPerMonth?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  maxTokensPerMonth?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  maxSpendPerMonth?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  maxRequestsPerDay?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  maxTokensPerDay?: number;

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

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