/**
 * Asset Entity - Catalogo Principal de Activos
 *
 * Maquinaria, equipo, vehiculos y herramientas de construccion.
 *
 * @module Assets (MAE-015)
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  ManyToOne,
  OneToMany,
  JoinColumn,
  Index,
} from 'typeorm';
import { AssetCategory } from './asset-category.entity';
import { AssetAssignment } from './asset-assignment.entity';
import { MaintenanceHistory } from './maintenance-history.entity';
import { FuelLog } from './fuel-log.entity';

export type AssetType =
  | 'heavy_machinery'
  | 'light_equipment'
  | 'vehicle'
  | 'tool'
  | 'computer'
  | 'furniture'
  | 'other';

export type AssetStatus =
  | 'available'
  | 'assigned'
  | 'in_maintenance'
  | 'in_transit'
  | 'inactive'
  | 'retired'
  | 'sold';

export type OwnershipType = 'owned' | 'leased' | 'rented' | 'borrowed';

@Entity('assets', { schema: 'assets' })
@Index(['tenantId', 'assetCode'], { unique: true })
@Index(['tenantId', 'assetType'])
@Index(['tenantId', 'status'])
@Index(['tenantId', 'categoryId'])
@Index(['tenantId', 'currentProjectId'])
@Index(['tenantId', 'serialNumber'])
export class Asset {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  @Index()
  tenantId!: string;

  // Identificacion
  @Column({ name: 'asset_code', length: 50 })
  assetCode!: string;

  @Column({ length: 255 })
  name!: string;

  @Column({ type: 'text', nullable: true })
  description?: string;

  // Clasificacion
  @Column({ name: 'category_id', type: 'uuid', nullable: true })
  categoryId?: string;

  @ManyToOne(() => AssetCategory, { nullable: true })
  @JoinColumn({ name: 'category_id' })
  category?: AssetCategory;

  @Column({
    name: 'asset_type',
    type: 'enum',
    enum: ['heavy_machinery', 'light_equipment', 'vehicle', 'tool', 'computer', 'furniture', 'other'],
    enumName: 'asset_type',
  })
  assetType!: AssetType;

  @Column({
    type: 'enum',
    enum: ['available', 'assigned', 'in_maintenance', 'in_transit', 'inactive', 'retired', 'sold'],
    enumName: 'asset_status',
    default: 'available',
  })
  status!: AssetStatus;

  @Column({
    name: 'ownership_type',
    type: 'enum',
    enum: ['owned', 'leased', 'rented', 'borrowed'],
    enumName: 'ownership_type',
    default: 'owned',
  })
  ownershipType!: OwnershipType;

  // Especificaciones tecnicas
  @Column({ length: 100, nullable: true })
  brand?: string;

  @Column({ length: 100, nullable: true })
  model?: string;

  @Column({ name: 'serial_number', length: 100, nullable: true })
  serialNumber?: string;

  @Column({ name: 'year_manufactured', type: 'int', nullable: true })
  yearManufactured?: number;

  @Column({ type: 'jsonb', nullable: true })
  specifications?: Record<string, any>;

  // Capacidades
  @Column({ length: 100, nullable: true })
  capacity?: string;

  @Column({ name: 'power_rating', length: 50, nullable: true })
  powerRating?: string;

  @Column({ name: 'fuel_type', length: 50, nullable: true })
  fuelType?: string;

  @Column({ name: 'fuel_capacity', type: 'decimal', precision: 10, scale: 2, nullable: true })
  fuelCapacity?: number;

  @Column({ name: 'fuel_consumption_rate', type: 'decimal', precision: 10, scale: 2, nullable: true })
  fuelConsumptionRate?: number;

  // Metricas de uso
  @Column({ name: 'current_hours', type: 'decimal', precision: 12, scale: 2, default: 0 })
  currentHours!: number;

  @Column({ name: 'current_kilometers', type: 'decimal', precision: 12, scale: 2, default: 0 })
  currentKilometers!: number;

  @Column({ name: 'last_usage_update', type: 'timestamptz', nullable: true })
  lastUsageUpdate?: Date;

  // Ubicacion actual
  @Column({ name: 'current_project_id', type: 'uuid', nullable: true })
  currentProjectId?: string;

  @Column({ name: 'current_location_name', length: 255, nullable: true })
  currentLocationName?: string;

  @Column({ name: 'current_latitude', type: 'decimal', precision: 10, scale: 8, nullable: true })
  currentLatitude?: number;

  @Column({ name: 'current_longitude', type: 'decimal', precision: 11, scale: 8, nullable: true })
  currentLongitude?: number;

  @Column({ name: 'last_location_update', type: 'timestamptz', nullable: true })
  lastLocationUpdate?: Date;

  // Informacion financiera
  @Column({ name: 'purchase_date', type: 'date', nullable: true })
  purchaseDate?: Date;

  @Column({ name: 'purchase_price', type: 'decimal', precision: 18, scale: 2, nullable: true })
  purchasePrice?: number;

  @Column({ name: 'purchase_currency', length: 3, default: 'MXN' })
  purchaseCurrency!: string;

  @Column({ name: 'supplier_id', type: 'uuid', nullable: true })
  supplierId?: string;

  @Column({ name: 'invoice_number', length: 100, nullable: true })
  invoiceNumber?: string;

  // Depreciacion
  @Column({ name: 'useful_life_years', type: 'int', nullable: true })
  usefulLifeYears?: number;

  @Column({ name: 'salvage_value', type: 'decimal', precision: 18, scale: 2, nullable: true })
  salvageValue?: number;

  @Column({ name: 'current_book_value', type: 'decimal', precision: 18, scale: 2, nullable: true })
  currentBookValue?: number;

  @Column({ name: 'accumulated_depreciation', type: 'decimal', precision: 18, scale: 2, default: 0 })
  accumulatedDepreciation!: number;

  @Column({ name: 'depreciation_method', length: 50, nullable: true })
  depreciationMethod?: string;

  @Column({ name: 'last_depreciation_date', type: 'date', nullable: true })
  lastDepreciationDate?: Date;

  // Arrendamiento (si aplica)
  @Column({ name: 'lease_start_date', type: 'date', nullable: true })
  leaseStartDate?: Date;

  @Column({ name: 'lease_end_date', type: 'date', nullable: true })
  leaseEndDate?: Date;

  @Column({ name: 'lease_monthly_rate', type: 'decimal', precision: 18, scale: 2, nullable: true })
  leaseMonthlyRate?: number;

  @Column({ name: 'lease_contract_number', length: 100, nullable: true })
  leaseContractNumber?: string;

  @Column({ name: 'lessor_name', length: 255, nullable: true })
  lessorName?: string;

  // Seguro
  @Column({ name: 'insurance_policy_number', length: 100, nullable: true })
  insurancePolicyNumber?: string;

  @Column({ name: 'insurance_company', length: 255, nullable: true })
  insuranceCompany?: string;

  @Column({ name: 'insurance_expiry_date', type: 'date', nullable: true })
  insuranceExpiryDate?: Date;

  @Column({ name: 'insurance_coverage_amount', type: 'decimal', precision: 18, scale: 2, nullable: true })
  insuranceCoverageAmount?: number;

  // Documentos
  @Column({ name: 'photo_url', length: 500, nullable: true })
  photoUrl?: string;

  @Column({ name: 'manual_url', length: 500, nullable: true })
  manualUrl?: string;

  @Column({ name: 'registration_document_url', length: 500, nullable: true })
  registrationDocumentUrl?: string;

  // Proximo mantenimiento
  @Column({ name: 'next_maintenance_date', type: 'date', nullable: true })
  nextMaintenanceDate?: Date;

  @Column({ name: 'next_maintenance_hours', type: 'decimal', precision: 12, scale: 2, nullable: true })
  nextMaintenanceHours?: number;

  @Column({ name: 'next_maintenance_kilometers', type: 'decimal', precision: 12, scale: 2, nullable: true })
  nextMaintenanceKilometers?: number;

  // Operador asignado
  @Column({ name: 'assigned_operator_id', type: 'uuid', nullable: true })
  assignedOperatorId?: string;

  // Notas y metadatos
  @Column({ type: 'text', nullable: true })
  notes?: string;

  @Column({ type: 'varchar', array: true, nullable: true })
  tags?: string[];

  @Column({ type: 'jsonb', nullable: true })
  metadata?: Record<string, any>;

  // Relaciones
  @OneToMany(() => AssetAssignment, (assignment) => assignment.asset)
  assignments?: AssetAssignment[];

  @OneToMany(() => MaintenanceHistory, (history) => history.asset)
  maintenanceHistory?: MaintenanceHistory[];

  @OneToMany(() => FuelLog, (log) => log.asset)
  fuelLogs?: FuelLog[];

  // Auditoria
  @Column({ name: 'created_by', type: 'uuid', nullable: true })
  createdBy?: string;

  @Column({ name: 'updated_by', type: 'uuid', nullable: true })
  updatedBy?: string;

  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt!: Date;

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
  updatedAt!: Date;

  @Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
  deletedAt?: Date;
}
