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

export enum ProductType {
  STORABLE = 'storable',
  CONSUMABLE = 'consumable',
  SERVICE = 'service',
}

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;

  @Column({
    type: 'boolean',
    default: true,
    nullable: false,
    name: 'is_storable',
    generated: 'STORED',
    asExpression: "product_type = '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;

  // 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;
}
