/**
 * Subcontractor DTOs - Data Transfer Objects para Subcontratistas
 *
 * Catalogo de subcontratistas.
 *
 * @module Contracts (MAI-012)
 */

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

/**
 * Especialidad del subcontratista
 */
export enum SubcontractorSpecialtyEnum {
  CIMENTACION = 'cimentacion',
  ESTRUCTURA = 'estructura',
  INSTALACIONES_ELECTRICAS = 'instalaciones_electricas',
  INSTALACIONES_HIDRAULICAS = 'instalaciones_hidraulicas',
  ACABADOS = 'acabados',
  URBANIZACION = 'urbanizacion',
  CARPINTERIA = 'carpinteria',
  HERRERIA = 'herreria',
  OTROS = 'otros',
}

/**
 * Estado del subcontratista
 */
export enum SubcontractorStatusEnum {
  ACTIVE = 'active',
  INACTIVE = 'inactive',
  BLACKLISTED = 'blacklisted',
}

/**
 * DTO para crear un nuevo subcontratista
 */
export class CreateSubcontractorDto {
  @IsString()
  @MinLength(3)
  @MaxLength(30)
  code: string;

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

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

  @IsString()
  @MinLength(12)
  @MaxLength(13)
  rfc: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(20)
  phone?: string;

  @IsOptional()
  @IsEmail()
  @MaxLength(255)
  email?: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(20)
  contactPhone?: string;

  @IsEnum(SubcontractorSpecialtyEnum)
  primarySpecialty: SubcontractorSpecialtyEnum;

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(18)
  clabe?: string;

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

/**
 * DTO para actualizar un subcontratista existente
 */
export class UpdateSubcontractorDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(30)
  code?: string;

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

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

  @IsOptional()
  @IsString()
  @MinLength(12)
  @MaxLength(13)
  rfc?: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(20)
  phone?: string;

  @IsOptional()
  @IsEmail()
  @MaxLength(255)
  email?: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(20)
  contactPhone?: string;

  @IsOptional()
  @IsEnum(SubcontractorSpecialtyEnum)
  primarySpecialty?: SubcontractorSpecialtyEnum;

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

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(18)
  clabe?: string;

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

/**
 * DTO para actualizar rating del subcontratista
 */
export class UpdateSubcontractorRatingDto {
  @IsNumber()
  @Min(0)
  @Max(5)
  rating: number;

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

/**
 * DTO para registrar incidente del subcontratista
 */
export class RegisterIncidentDto {
  @IsString()
  @MinLength(10)
  description: string;

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

/**
 * DTO para marcar subcontratista en lista negra
 */
export class BlacklistSubcontractorDto {
  @IsString()
  @MinLength(10)
  reason: string;
}

/**
 * DTO para filtrar subcontratistas en listados
 */
export class SubcontractorFiltersDto {
  @IsOptional()
  @IsEnum(SubcontractorSpecialtyEnum)
  primarySpecialty?: SubcontractorSpecialtyEnum;

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

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(5)
  minRating?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(5)
  maxRating?: number;

  @IsOptional()
  @IsNumber()
  @Min(0)
  minContracts?: 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 de respuesta para un subcontratista
 */
export class SubcontractorResponseDto {
  id: string;
  tenantId: string;
  code: string;
  businessName: string;
  tradeName?: string;
  rfc: string;
  address?: string;
  phone?: string;
  email?: string;
  contactName?: string;
  contactPhone?: string;
  primarySpecialty: SubcontractorSpecialtyEnum;
  secondarySpecialties?: string[];
  status: SubcontractorStatusEnum;
  totalContracts: number;
  completedContracts: number;
  averageRating: string;
  totalIncidents: number;
  bankName?: string;
  bankAccount?: string;
  clabe?: string;
  notes?: string;
  activeContractsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
}
