import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  OneToMany,
} from 'typeorm';
import { StockQuant } from './stock-quant.entity.js';
import { Lot } from './lot.entity.js';

/**
 * Inventory Product Entity (schema: inventory.products)
 *
 * ADAPTADO PARA ERP TRANSPORTISTAS:
 * Este módulo se usa principalmente para gestionar refacciones de flota.
 * Incluye campos específicos para identificar partes de vehículos y su
 * compatibilidad con unidades de la flota.
 *
 * NOTE: This is NOT a duplicate of products/entities/product.entity.ts
 *
 * Key differences:
 * - This entity: inventory.products - Warehouse/stock management focused (Odoo-style)
 *   - Has: valuationMethod, tracking (lot/serial), isStorable, StockQuant/Lot relations
 *   - Used by: Inventory module for stock tracking, valuation, picking operations
 *   - TRANSPORT: tipoRefaccion, numeroParte, unidadesCompatibles
 *
 * - Products entity: products.products - Commerce/retail focused
 *   - Has: SAT codes, tax rates, detailed dimensions, min/max stock, reorder points
 *   - Used by: Sales, purchases, invoicing
 *
 * These are intentionally separate by domain. A product in the products schema
 * may reference an inventory product for stock tracking purposes.
 */
export enum ProductType {
  STORABLE = 'storable',
  CONSUMABLE = 'consumable',
  SERVICE = 'service',
}

/**
 * Tipo de Refacción (específico para transporte)
 */
export enum TipoRefaccion {
  MOTOR = 'MOTOR',
  FRENOS = 'FRENOS',
  LLANTAS = 'LLANTAS',
  SUSPENSION = 'SUSPENSION',
  TRANSMISION = 'TRANSMISION',
  ELECTRICO = 'ELECTRICO',
  CARROCERIA = 'CARROCERIA',
  REFRIGERACION = 'REFRIGERACION',
  LUBRICANTES = 'LUBRICANTES',
  FILTROS = 'FILTROS',
  ACCESORIOS = 'ACCESORIOS',
  OTRO = 'OTRO',
}

export enum TrackingType {
  NONE = 'none',
  LOT = 'lot',
  SERIAL = 'serial',
}

export enum ValuationMethod {
  STANDARD = 'standard',
  FIFO = 'fifo',
  AVERAGE = 'average',
}

@Entity({ schema: 'inventory', name: 'products' })
@Index('idx_products_tenant_id', ['tenantId'])
@Index('idx_products_code', ['code'], { where: 'deleted_at IS NULL' })
@Index('idx_products_barcode', ['barcode'], { where: 'deleted_at IS NULL' })
@Index('idx_products_category_id', ['categoryId'])
@Index('idx_products_active', ['active'], { where: 'deleted_at IS NULL' })
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

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

  @Column({ type: 'varchar', length: 255, nullable: false })
  name: string;

  @Column({ type: 'varchar', length: 100, nullable: true, unique: true })
  code: string | null;

  @Column({ type: 'varchar', length: 100, nullable: true })
  barcode: string | null;

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

  @Column({
    type: 'enum',
    enum: ProductType,
    default: ProductType.STORABLE,
    nullable: false,
    name: 'product_type',
  })
  productType: ProductType;

  @Column({
    type: 'enum',
    enum: TrackingType,
    default: TrackingType.NONE,
    nullable: false,
  })
  tracking: TrackingType;

  @Column({ type: 'uuid', nullable: true, name: 'category_id' })
  categoryId: string | null;

  @Column({ type: 'uuid', nullable: false, name: 'uom_id' })
  uomId: string;

  @Column({ type: 'uuid', nullable: true, name: 'purchase_uom_id' })
  purchaseUomId: string | null;

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

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

  @Column({
    type: 'enum',
    enum: ValuationMethod,
    default: ValuationMethod.FIFO,
    nullable: false,
    name: 'valuation_method',
  })
  valuationMethod: ValuationMethod;

  // Computed field: is_storable is derived from product_type = 'storable'
  // This should be handled at database level or computed on read
  @Column({
    type: 'boolean',
    default: true,
    nullable: false,
    name: 'is_storable',
  })
  isStorable: boolean;

  @Column({ type: 'decimal', precision: 12, scale: 4, nullable: true })
  weight: number | null;

  @Column({ type: 'decimal', precision: 12, scale: 4, nullable: true })
  volume: number | null;

  @Column({ type: 'boolean', default: true, nullable: false, name: 'can_be_sold' })
  canBeSold: boolean;

  @Column({ type: 'boolean', default: true, nullable: false, name: 'can_be_purchased' })
  canBePurchased: boolean;

  @Column({ type: 'varchar', length: 500, nullable: true, name: 'image_url' })
  imageUrl: string | null;

  @Column({ type: 'boolean', default: true, nullable: false })
  active: boolean;

  // === CAMPOS ESPECÍFICOS PARA REFACCIONES DE FLOTA ===

  /**
   * Tipo de refacción (para clasificación en mantenimiento)
   */
  @Column({
    type: 'enum',
    enum: TipoRefaccion,
    nullable: true,
    name: 'tipo_refaccion',
  })
  tipoRefaccion: TipoRefaccion | null;

  /**
   * Número de parte del fabricante (OEM)
   */
  @Column({ type: 'varchar', length: 100, nullable: true, name: 'numero_parte' })
  numeroParte: string | null;

  /**
   * Número de parte alterno/equivalente
   */
  @Column({ type: 'varchar', length: 100, nullable: true, name: 'numero_parte_alterno' })
  numeroParteAlterno: string | null;

  /**
   * Marca del fabricante de la refacción
   */
  @Column({ type: 'varchar', length: 100, nullable: true, name: 'marca_refaccion' })
  marcaRefaccion: string | null;

  /**
   * IDs de unidades donde esta refacción es compatible
   * Referencia a fleet.unidades
   */
  @Column({ type: 'uuid', array: true, nullable: true, name: 'unidades_compatibles' })
  unidadesCompatibles: string[] | null;

  /**
   * Modelos de vehículos compatibles (texto libre)
   * Ej: "Kenworth T680 2020-2024, Freightliner Cascadia"
   */
  @Column({ type: 'text', nullable: true, name: 'modelos_compatibles' })
  modelosCompatibles: string | null;

  /**
   * Vida útil estimada en kilómetros
   */
  @Column({ type: 'int', nullable: true, name: 'vida_util_km' })
  vidaUtilKm: number | null;

  /**
   * Vida útil estimada en horas de operación
   */
  @Column({ type: 'int', nullable: true, name: 'vida_util_horas' })
  vidaUtilHoras: number | null;

  /**
   * Indica si es una refacción crítica (afecta operación)
   */
  @Column({ type: 'boolean', default: false, name: 'es_critica' })
  esCritica: boolean;

  /**
   * Stock mínimo recomendado para refacciones críticas
   */
  @Column({ type: 'int', nullable: true, name: 'stock_minimo_critico' })
  stockMinimoCritico: number | null;

  // === FIN CAMPOS REFACCIONES ===

  // Relations
  @OneToMany(() => StockQuant, (stockQuant) => stockQuant.product)
  stockQuants: StockQuant[];

  @OneToMany(() => Lot, (lot) => lot.product)
  lots: Lot[];

  // Auditoría
  @CreateDateColumn({ name: 'created_at', type: 'timestamp' })
  createdAt: Date;

  @Column({ type: 'uuid', nullable: true, name: 'created_by' })
  createdBy: string | null;

  @UpdateDateColumn({
    name: 'updated_at',
    type: 'timestamp',
    nullable: true,
  })
  updatedAt: Date | null;

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

  @Column({ type: 'timestamp', nullable: true, name: 'deleted_at' })
  deletedAt: Date | null;

  @Column({ type: 'uuid', nullable: true, name: 'deleted_by' })
  deletedBy: string | null;
}
