/**
 * Tender DTOs - Data Transfer Objects para Licitaciones Formales
 *
 * Representa una licitacion formal vinculada a una oportunidad.
 *
 * @module Bidding (MAI-018)
 */

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

/**
 * Tipo de licitacion
 */
export enum TenderType {
  PUBLIC = 'public',
  PRIVATE = 'private',
  INVITATION_ONLY = 'invitation_only',
}

/**
 * Estado de la licitacion
 */
export enum TenderStatus {
  DRAFT = 'draft',
  PUBLISHED = 'published',
  RECEIVING = 'receiving',
  EVALUATING = 'evaluating',
  AWARDED = 'awarded',
  CANCELLED = 'cancelled',
  CONVERTING = 'converting',
  CONVERTED = 'converted',
}

/**
 * DTO para crear una nueva licitacion
 */
export class CreateTenderDto {
  @IsUUID()
  opportunityId: string;

  @IsEnum(TenderType)
  type: TenderType;

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

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

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

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

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

  @IsDateString()
  proposalDeadline: string;

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  contractDurationDays?: number;
}

/**
 * DTO para actualizar una licitacion existente
 */
export class UpdateTenderDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  number?: string;

  @IsOptional()
  @IsEnum(TenderType)
  type?: TenderType;

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

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

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

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

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

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

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

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

  @IsOptional()
  @IsEnum(TenderStatus)
  status?: TenderStatus;
}

/**
 * DTO para publicar una licitacion
 */
export class PublishTenderDto {
  @IsOptional()
  @IsString()
  notes?: string;

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

/**
 * DTO para adjudicar una licitacion a una propuesta ganadora
 */
export class AwardTenderDto {
  @IsUUID()
  proposalId: string;

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

  @IsOptional()
  @IsString()
  notes?: string;
}

/**
 * DTO para cancelar una licitacion
 */
export class CancelTenderDto {
  @IsString()
  @MinLength(10)
  reason: string;
}

/**
 * DTO para filtrar licitaciones en listados
 */
export class TenderFiltersDto {
  @IsOptional()
  @IsUUID()
  opportunityId?: string;

  @IsOptional()
  @IsEnum(TenderType)
  type?: TenderType;

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

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

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

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

  @IsOptional()
  @IsDateString()
  dateTo?: 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 licitacion
 */
export class TenderResponseDto {
  id: string;
  tenantId: string;
  opportunityId: string;
  opportunity?: {
    id: string;
    code: string;
    title: string;
    clientName: string;
  };
  number: string;
  type: TenderType;
  title: string;
  description?: string;
  referenceAmount?: string;
  publicationDate?: Date;
  clarificationMeetingDate?: Date;
  proposalDeadline: Date;
  awardDate?: Date;
  contractDurationDays?: number;
  status: TenderStatus;
  winnerId?: string;
  winner?: {
    id: string;
    vendorId: string;
    proposedAmount: string;
  };
  proposalsCount?: number;
  documentsCount?: number;
  calendarEventsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}
