/**
 * ContractAddendum DTOs - Data Transfer Objects para Addendas de Contratos
 *
 * Addendas y modificaciones a contratos.
 *
 * @module Contracts (MAI-012)
 */

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

/**
 * Tipo de addenda
 */
export enum AddendumTypeEnum {
  EXTENSION = 'extension',
  AMOUNT_INCREASE = 'amount_increase',
  AMOUNT_DECREASE = 'amount_decrease',
  SCOPE_CHANGE = 'scope_change',
  TERMINATION = 'termination',
  OTHER = 'other',
}

/**
 * Estado de la addenda
 */
export enum AddendumStatusEnum {
  DRAFT = 'draft',
  REVIEW = 'review',
  APPROVED = 'approved',
  REJECTED = 'rejected',
}

/**
 * DTO para crear una nueva addenda
 */
export class CreateAddendumDto {
  @IsUUID()
  contractId: string;

  @IsString()
  @MinLength(3)
  @MaxLength(50)
  addendumNumber: string;

  @IsEnum(AddendumTypeEnum)
  addendumType: AddendumTypeEnum;

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

  @IsString()
  @MinLength(10)
  description: string;

  @IsDateString()
  effectiveDate: string;

  @IsOptional()
  @IsNumber()
  adjustmentAmount?: number;

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(500)
  documentUrl?: string;

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

/**
 * DTO para actualizar una addenda existente
 */
export class UpdateAddendumDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  addendumNumber?: string;

  @IsOptional()
  @IsEnum(AddendumTypeEnum)
  addendumType?: AddendumTypeEnum;

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

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

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

  @IsOptional()
  @IsNumber()
  adjustmentAmount?: number;

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

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(500)
  documentUrl?: string;

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

/**
 * DTO para aprobar una addenda
 */
export class ApproveAddendumDto {
  @IsOptional()
  @IsString()
  notes?: string;
}

/**
 * DTO para rechazar una addenda
 */
export class RejectAddendumDto {
  @IsString()
  @MinLength(10)
  rejectionReason: string;
}

/**
 * DTO para filtrar addendas en listados
 */
export class AddendumFiltersDto {
  @IsOptional()
  @IsUUID()
  contractId?: string;

  @IsOptional()
  @IsEnum(AddendumTypeEnum)
  addendumType?: AddendumTypeEnum;

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

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

  @IsOptional()
  @IsDateString()
  effectiveDateTo?: 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 addenda
 */
export class AddendumResponseDto {
  id: string;
  tenantId: string;
  contractId: string;
  contract?: {
    id: string;
    contractNumber: string;
    name: string;
  };
  addendumNumber: string;
  addendumType: AddendumTypeEnum;
  title: string;
  description: string;
  effectiveDate: Date;
  newEndDate?: Date;
  amountChange: string;
  newContractAmount?: string;
  scopeChanges?: string;
  status: AddendumStatusEnum;
  approvedAt?: Date;
  approvedById?: string;
  approvedBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  rejectionReason?: string;
  documentUrl?: string;
  notes?: string;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
}
