/**
 * Vendor DTOs - Data Transfer Objects para Proveedores/Contratistas
 *
 * Representa proveedores y contratistas que participan en licitaciones.
 *
 * @module Bidding (MAI-018)
 */

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

/**
 * Interface para certificaciones del proveedor
 */
export class VendorCertificationDto {
  @IsString()
  @MaxLength(255)
  name: string;

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

  @IsString()
  issuedDate: string;

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

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

/**
 * Interface para historial de desempeno del proveedor
 */
export class VendorPerformanceEntryDto {
  @IsString()
  @MaxLength(255)
  projectName: string;

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

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

  @IsString()
  completedDate: string;

  @IsNumber()
  @Min(1)
  @Max(5)
  rating: number;

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

/**
 * DTO para crear un nuevo proveedor/contratista
 */
export class CreateVendorDto {
  @IsString()
  @MinLength(3)
  @MaxLength(20)
  code: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(13)
  @Matches(/^[A-Z&]{3,4}[0-9]{6}[A-Z0-9]{3}$/, {
    message: 'RFC debe tener formato valido (ej: XAXX010101000)',
  })
  rfc?: string;

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  @Max(5)
  rating?: number;

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => VendorCertificationDto)
  certifications?: VendorCertificationDto[];

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

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

  @IsOptional()
  @IsString()
  @MaxLength(50)
  contactPhone?: string;
}

/**
 * DTO para actualizar un proveedor existente
 */
export class UpdateVendorDto {
  @IsOptional()
  @IsString()
  @MinLength(3)
  @MaxLength(20)
  code?: string;

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

  @IsOptional()
  @IsString()
  @MaxLength(13)
  @Matches(/^[A-Z&]{3,4}[0-9]{6}[A-Z0-9]{3}$/, {
    message: 'RFC debe tener formato valido (ej: XAXX010101000)',
  })
  rfc?: string;

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  @Max(5)
  rating?: number;

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => VendorCertificationDto)
  certifications?: VendorCertificationDto[];

  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => VendorPerformanceEntryDto)
  performanceHistory?: VendorPerformanceEntryDto[];

  @IsOptional()
  @IsBoolean()
  documentationValid?: boolean;

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

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

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

  @IsOptional()
  @IsBoolean()
  isActive?: boolean;
}

/**
 * DTO para actualizar la calificacion de un proveedor
 */
export class UpdateRatingDto {
  @IsNumber()
  @Min(1)
  @Max(5)
  rating: number;

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

/**
 * DTO para agregar entrada de desempeno
 */
export class AddPerformanceEntryDto {
  @IsString()
  @MaxLength(255)
  projectName: string;

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

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

  @IsString()
  completedDate: string;

  @IsNumber()
  @Min(1)
  @Max(5)
  rating: number;

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

/**
 * DTO para agregar certificacion
 */
export class AddCertificationDto {
  @IsString()
  @MaxLength(255)
  name: string;

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

  @IsString()
  issuedDate: string;

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

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

/**
 * DTO para filtrar proveedores en listados
 */
export class VendorFiltersDto {
  @IsOptional()
  @IsString()
  search?: string;

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

  @IsOptional()
  @IsBoolean()
  isActive?: boolean;

  @IsOptional()
  @IsBoolean()
  documentationValid?: boolean;

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

  @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 proveedor
 */
export class VendorResponseDto {
  id: string;
  tenantId: string;
  code: string;
  businessName: string;
  rfc?: string;
  specialties?: string[];
  rating?: number;
  certifications?: VendorCertificationDto[];
  performanceHistory?: VendorPerformanceEntryDto[];
  documentationValid: boolean;
  contactName?: string;
  contactEmail?: string;
  contactPhone?: string;
  isActive: boolean;
  proposalsCount?: number;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}
