/**
 * Opportunity DTOs - Data Transfer Objects para Oportunidades de Licitacion
 *
 * Representa oportunidades de licitacion/proyecto en el pipeline comercial.
 *
 * @module Bidding (MAI-018)
 */

import {
  IsString,
  IsOptional,
  IsEnum,
  IsNumber,
  IsDateString,
  MinLength,
  MaxLength,
  Min,
} from 'class-validator';

/**
 * Fuente de la oportunidad
 */
export enum OpportunitySource {
  GOVERNMENT_PORTAL = 'government_portal',
  PRIVATE_CLIENT = 'private_client',
  REFERRAL = 'referral',
  OTHER = 'other',
}

/**
 * Estado de la oportunidad en el pipeline
 */
export enum OpportunityStatus {
  REGISTERED = 'registered',
  EVALUATING = 'evaluating',
  GO = 'go',
  NO_GO = 'no_go',
  PREPARING = 'preparing',
  CONVERTED = 'converted',
}

/**
 * Prioridad de la oportunidad
 */
export enum Priority {
  HIGH = 'high',
  MEDIUM = 'medium',
  LOW = 'low',
}

/**
 * DTO para crear una nueva oportunidad
 */
export class CreateOpportunityDto {
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  code: string;

  @IsString()
  @MinLength(5)
  @MaxLength(255)
  title: string;

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

  @IsEnum(OpportunitySource)
  source: OpportunitySource;

  @IsString()
  @MaxLength(255)
  clientName: string;

  @IsString()
  @MaxLength(100)
  projectType: string;

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

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

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

  @IsOptional()
  @IsEnum(Priority)
  priority?: Priority;

  @IsDateString()
  deadlineDate: string;
}

/**
 * DTO para actualizar una oportunidad existente
 */
export class UpdateOpportunityDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  code?: string;

  @IsOptional()
  @IsString()
  @MinLength(5)
  @MaxLength(255)
  title?: string;

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

  @IsOptional()
  @IsEnum(OpportunitySource)
  source?: OpportunitySource;

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

  @IsOptional()
  @IsString()
  @MaxLength(100)
  projectType?: string;

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

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

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

  @IsOptional()
  @IsEnum(Priority)
  priority?: Priority;

  @IsOptional()
  @IsDateString()
  deadlineDate?: string;
}

/**
 * DTO para evaluar una oportunidad (Go/No-Go decision)
 */
export class EvaluateOpportunityDto {
  @IsEnum(['go', 'no_go'])
  decision: 'go' | 'no_go';

  @IsString()
  @MinLength(10)
  reason: string;
}

/**
 * DTO para filtrar oportunidades en listados
 */
export class OpportunityFiltersDto {
  @IsOptional()
  @IsEnum(OpportunitySource)
  source?: OpportunitySource;

  @IsOptional()
  @IsEnum(OpportunityStatus)
  status?: OpportunityStatus;

  @IsOptional()
  @IsEnum(Priority)
  priority?: Priority;

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

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

  @IsOptional()
  @IsDateString()
  dateFrom?: string;

  @IsOptional()
  @IsDateString()
  dateTo?: string;

  @IsOptional()
  @IsDateString()
  deadlineFrom?: string;

  @IsOptional()
  @IsDateString()
  deadlineTo?: string;

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

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

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

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

  @IsOptional()
  @IsEnum(['ASC', 'DESC'])
  sortOrder?: 'ASC' | 'DESC';
}

/**
 * DTO de respuesta para una oportunidad
 */
export class OpportunityResponseDto {
  id: string;
  tenantId: string;
  code: string;
  title: string;
  description?: string;
  source: OpportunitySource;
  clientName: string;
  projectType: string;
  location?: string;
  estimatedAmount?: string;
  estimatedUnits?: number;
  status: OpportunityStatus;
  goDecisionDate?: Date;
  goDecisionReason?: string;
  priority: Priority;
  deadlineDate: Date;
  tendersCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}
