/**
 * Contract DTOs - Data Transfer Objects para Contratos
 *
 * Contratos con clientes y subcontratistas.
 *
 * @module Contracts (MAI-012)
 */

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

/**
 * Tipo de contrato
 */
export enum ContractTypeEnum {
  CLIENT = 'client',
  SUBCONTRACTOR = 'subcontractor',
}

/**
 * Estado del contrato
 */
export enum ContractStatusEnum {
  DRAFT = 'draft',
  REVIEW = 'review',
  APPROVED = 'approved',
  ACTIVE = 'active',
  COMPLETED = 'completed',
  TERMINATED = 'terminated',
}

/**
 * Tipo de contrato cliente
 */
export enum ClientContractTypeEnum {
  DESARROLLO = 'desarrollo',
  LLAVE_EN_MANO = 'llave_en_mano',
  ADMINISTRACION = 'administracion',
}

/**
 * DTO para crear un nuevo contrato
 */
export class CreateContractDto {
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  contractNumber: string;

  @IsEnum(ContractTypeEnum)
  type: ContractTypeEnum;

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

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

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

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

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

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

  @IsDateString()
  startDate: string;

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

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

  @IsOptional()
  @IsString()
  @MaxLength(3)
  currency?: string;

  @IsOptional()
  @IsEnum(ClientContractTypeEnum)
  clientContractType?: ClientContractTypeEnum;

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

  @IsOptional()
  @IsString()
  @MaxLength(13)
  clientRfc?: string;

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

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

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

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(100)
  retentionPercentage?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(100)
  advancePercentage?: number;

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

/**
 * DTO para actualizar un contrato existente
 */
export class UpdateContractDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(50)
  contractNumber?: string;

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

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

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

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

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

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

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

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(3)
  currency?: string;

  @IsOptional()
  @IsEnum(ClientContractTypeEnum)
  clientContractType?: ClientContractTypeEnum;

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

  @IsOptional()
  @IsString()
  @MaxLength(13)
  clientRfc?: string;

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

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

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

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(100)
  retentionPercentage?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(100)
  advancePercentage?: number;

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

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

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

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

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

/**
 * DTO para filtrar contratos en listados
 */
export class ContractFiltersDto {
  @IsOptional()
  @IsEnum(ContractTypeEnum)
  type?: ContractTypeEnum;

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

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

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

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

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

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

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

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

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

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

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

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

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

  @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 para aprobar un contrato
 */
export class ApproveContractDto {
  @IsOptional()
  @IsString()
  notes?: string;

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

/**
 * DTO para aprobacion legal del contrato
 */
export class LegalApproveContractDto {
  @IsOptional()
  @IsString()
  notes?: string;
}

/**
 * DTO para terminar un contrato
 */
export class TerminateContractDto {
  @IsString()
  @MinLength(10)
  reason: string;

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

/**
 * DTO para firmar un contrato
 */
export class SignContractDto {
  @IsOptional()
  @IsString()
  @MaxLength(500)
  signedDocumentUrl?: string;

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

/**
 * DTO de respuesta para un contrato
 */
export class ContractResponseDto {
  id: string;
  tenantId: string;
  projectId?: string;
  project?: {
    id: string;
    code: string;
    name: string;
  };
  fraccionamientoId?: string;
  fraccionamiento?: {
    id: string;
    code: string;
    name: string;
  };
  contractNumber: string;
  contractType: ContractTypeEnum;
  clientContractType?: ClientContractTypeEnum;
  name: string;
  description?: string;
  clientName?: string;
  clientRfc?: string;
  clientAddress?: string;
  subcontractorId?: string;
  subcontractor?: {
    id: string;
    code: string;
    businessName: string;
  };
  specialty?: string;
  startDate: Date;
  endDate: Date;
  contractAmount: string;
  currency: string;
  paymentTerms?: string;
  retentionPercentage: string;
  advancePercentage: string;
  status: ContractStatusEnum;
  submittedAt?: Date;
  legalApprovedAt?: Date;
  approvedAt?: Date;
  signedAt?: Date;
  terminatedAt?: Date;
  terminationReason?: string;
  documentUrl?: string;
  signedDocumentUrl?: string;
  progressPercentage: string;
  invoicedAmount: string;
  paidAmount: string;
  remainingAmount?: string;
  isExpiring?: boolean;
  notes?: string;
  addendumsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
}
