/**
 * SupplierConstruction DTOs - Data Transfer Objects para Proveedores de Construccion
 *
 * Extension de proveedores con informacion especifica para construccion.
 *
 * @module Purchase (MAI-004)
 */

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

/**
 * DTO para crear una nueva extension de proveedor para construccion
 */
export class CreateSupplierConstructionDto {
  @IsUUID()
  supplierId: string;

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

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

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

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

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

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

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

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

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

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

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

/**
 * DTO para actualizar un proveedor de construccion existente
 */
export class UpdateSupplierConstructionDto {
  @IsOptional()
  @IsBoolean()
  isMaterialsSupplier?: boolean;

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

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

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

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

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

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

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

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

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

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

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

/**
 * DTO para actualizar la evaluacion de un proveedor
 */
export class UpdateSupplierEvaluationDto {
  @IsOptional()
  @IsNumber()
  @Min(1)
  @Max(5)
  qualityRating?: number;

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

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

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

/**
 * DTO para filtrar proveedores de construccion en listados
 */
export class SupplierConstructionFiltersDto {
  @IsOptional()
  @IsBoolean()
  isMaterialsSupplier?: boolean;

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

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

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

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

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

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

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

  @IsOptional()
  @IsNumber()
  @Min(1)
  @Max(100)
  limit?: number;

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

  @IsOptional()
  @IsEnum(['ASC', 'DESC'])
  sortOrder?: 'ASC' | 'DESC';
}

/**
 * DTO de respuesta para un proveedor de construccion
 */
export class SupplierConstructionResponseDto {
  id: string;
  tenantId: string;
  supplierId: string;
  supplier?: {
    id: string;
    code: string;
    name: string;
    rfc?: string;
  };
  isMaterialsSupplier: boolean;
  isServicesSupplier: boolean;
  isEquipmentSupplier: boolean;
  specialties?: string[];
  qualityRating?: number;
  deliveryRating?: number;
  priceRating?: number;
  overallRating?: number;
  lastEvaluationDate?: Date;
  creditLimit?: number;
  paymentDays: number;
  hasValidDocuments: boolean;
  documentsExpiryDate?: Date;
  createdAt: Date;
  createdById?: string;
  createdBy?: {
    id: string;
    firstName: string;
    lastName: string;
  };
  updatedAt: Date;
  updatedById?: string;
}
