/**
 * Asset DTOs - Data Transfer Objects para Activos
 *
 * Maquinaria, equipo, vehiculos y herramientas de construccion.
 *
 * @module Assets (MAE-015)
 */

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

/**
 * Tipo de activo
 */
export enum AssetType {
  HEAVY_MACHINERY = 'heavy_machinery',
  LIGHT_EQUIPMENT = 'light_equipment',
  VEHICLE = 'vehicle',
  TOOL = 'tool',
  COMPUTER = 'computer',
  FURNITURE = 'furniture',
  OTHER = 'other',
}

/**
 * Estado del activo
 */
export enum AssetStatus {
  AVAILABLE = 'available',
  ASSIGNED = 'assigned',
  IN_MAINTENANCE = 'in_maintenance',
  IN_TRANSIT = 'in_transit',
  INACTIVE = 'inactive',
  RETIRED = 'retired',
  SOLD = 'sold',
}

/**
 * Tipo de propiedad
 */
export enum OwnershipType {
  OWNED = 'owned',
  LEASED = 'leased',
  RENTED = 'rented',
  BORROWED = 'borrowed',
}

/**
 * Metodo de depreciacion
 */
export enum DepreciationMethod {
  STRAIGHT_LINE = 'straight_line',
  DECLINING_BALANCE = 'declining_balance',
  UNITS_OF_PRODUCTION = 'units_of_production',
  SUM_OF_YEARS = 'sum_of_years',
}

/**
 * DTO para crear un nuevo activo
 */
export class CreateAssetDto {
  @IsString()
  @MinLength(1)
  @MaxLength(50)
  code: string;

  @IsString()
  @MinLength(2)
  @MaxLength(255)
  name: string;

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

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

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

  @IsOptional()
  @IsEnum(OwnershipType)
  ownershipType?: OwnershipType;

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

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

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

  @IsOptional()
  @IsNumber()
  @Min(1900)
  @Max(2100)
  yearManufactured?: number;

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

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

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

  @IsOptional()
  @IsEnum(DepreciationMethod)
  depreciationMethod?: DepreciationMethod;

  @IsOptional()
  @IsNumber()
  @IsPositive()
  @Max(600)
  usefulLifeMonths?: number;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * DTO para actualizar un activo existente
 */
export class UpdateAssetDto {
  @IsOptional()
  @IsString()
  @MinLength(1)
  @MaxLength(50)
  code?: string;

  @IsOptional()
  @IsString()
  @MinLength(2)
  @MaxLength(255)
  name?: string;

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

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

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

  @IsOptional()
  @IsEnum(OwnershipType)
  ownershipType?: OwnershipType;

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

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

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

  @IsOptional()
  @IsNumber()
  @Min(1900)
  @Max(2100)
  yearManufactured?: number;

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

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

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

  @IsOptional()
  @IsEnum(DepreciationMethod)
  depreciationMethod?: DepreciationMethod;

  @IsOptional()
  @IsNumber()
  @IsPositive()
  @Max(600)
  usefulLifeMonths?: number;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @IsOptional()
  @IsUUID()
  assignedOperatorId?: string;
}

/**
 * DTO para filtrar activos en listados
 */
export class AssetFiltersDto {
  @IsOptional()
  @IsUUID()
  categoryId?: string;

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

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

  @IsOptional()
  @IsEnum(OwnershipType)
  ownershipType?: OwnershipType;

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

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

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

  @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 para asignar un activo a un proyecto
 */
export class AssignAssetDto {
  @IsUUID()
  projectId: string;

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

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

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

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

/**
 * DTO para actualizar metricas de uso
 */
export class UpdateUsageMetricsDto {
  @IsOptional()
  @IsNumber()
  @Min(0)
  currentHours?: number;

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

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

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

  @IsOptional()
  @IsString()
  @MaxLength(255)
  currentLocationName?: string;
}

/**
 * DTO de respuesta para un activo
 */
export class AssetResponseDto {
  id: string;
  tenantId: string;
  assetCode: string;
  name: string;
  description?: string;
  categoryId?: string;
  category?: {
    id: string;
    name: string;
    code: string;
  };
  assetType: AssetType;
  status: AssetStatus;
  ownershipType: OwnershipType;
  brand?: string;
  model?: string;
  serialNumber?: string;
  yearManufactured?: number;
  purchaseDate?: Date;
  purchasePrice?: number;
  purchaseCurrency: string;
  currentBookValue?: number;
  currentHours: number;
  currentKilometers: number;
  currentProjectId?: string;
  currentLocationName?: string;
  assignedOperatorId?: string;
  nextMaintenanceDate?: Date;
  photoUrl?: string;
  tags?: string[];
  createdAt: Date;
  updatedAt: Date;
}
