import { BaseEntity } from '@edr/api-common';
import { CargoUnitOfMeasure } from '@edr/types';
import {
  Column,
  Entity,
  Index,
  JoinColumn,
  JoinTable,
  ManyToMany,
  ManyToOne,
  OneToMany,
} from 'typeorm';
import { WagonType } from '../../wagon-types/entities/wagon-type.entity';

@Entity({ schema: 'freight', name: 'cargo_types' })
@Index(['isActive'])
@Index(['displayOrder'])
@Index(['parentGroupId'])
@Index(['code'])
export class CargoType extends BaseEntity {
  @Column({ name: 'code', type: 'varchar', length: 50, unique: true, default: '' })
  code!: string;

  @Column({ name: 'cargo_type_name', type: 'varchar', length: 255 })
  cargoTypeName!: string;

  @Column({ name: 'parent_group_id', type: 'uuid', nullable: true })
  parentGroupId?: string | null;

  /**
   * How this cargo's quantity is measured: PER_TON (bulk) or PER_ITEM
   * (break-bulk). Nullable for container/legacy cargo, which is counted by
   * container. Drives the unit shown when ordering against a general contract.
   */
  @Column({ name: 'unit_of_measure', type: 'varchar', length: 16, nullable: true })
  unitOfMeasure?: CargoUnitOfMeasure | null;

  /**
   * Wagon types that can carry this (bulk) cargo. Train scheduling resolves the
   * bulk wagon type through this list, picking whichever type the schedule's
   * train (or yard) actually has. Grouping rows and container/legacy cargo
   * leave it empty; scheduling throws if a scheduled bulk cargo type has none.
   */
  @ManyToMany(() => WagonType)
  @JoinTable({
    name: 'cargo_type_wagon_types',
    schema: 'freight',
    joinColumn: { name: 'cargo_type_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'wagon_type_id', referencedColumnName: 'id' },
  })
  wagonTypes?: WagonType[];

  @Column({ name: 'requires_director_approval', type: 'boolean', default: false })
  requiresDirectorApproval!: boolean;

  /**
   * When true, any booking of this cargo type incurs the flat LASHING surcharge
   * (the LASHING-trigger rate). Set on commodities that need EDR-provided
   * lashing/securing; leave false for cargo that ships without it.
   */
  @Column({ name: 'has_lashing', type: 'boolean', default: false })
  hasLashing!: boolean;

  @Column({ name: 'is_active', type: 'boolean', default: true })
  isActive!: boolean;

  @Column({ name: 'display_order', type: 'int', default: 1 })
  displayOrder!: number;

  @ManyToOne(() => CargoType, (ct) => ct.children, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'parent_group_id' })
  parent?: CargoType | null;

  @OneToMany(() => CargoType, (ct) => ct.parent)
  children?: CargoType[];
}
