import { BaseEntity } from '@edr/api-common';
import { TrainSetWagonStatus } from '@edr/types';
import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from 'typeorm';

import { WagonBookingAllocation } from '../../train-schedules/entities/wagon-booking-allocation.entity';
import { Wagon } from '../../wagons/entities/wagon.entity';
import { WagonType } from '../../wagon-types/entities/wagon-type.entity';
import { TrainSet } from './train-set.entity';

export const TRAIN_SET_WAGON_STATUSES = [
  TrainSetWagonStatus.Planned,
  TrainSetWagonStatus.Reserved,
  TrainSetWagonStatus.Loaded,
  TrainSetWagonStatus.Departed,
] as const;

export type TrainSetWagonStatusType = (typeof TRAIN_SET_WAGON_STATUSES)[number];

@Entity({ schema: 'freight', name: 'train_set_wagons' })
@Index(['trainSetId', 'sequenceNo'], { unique: true })
export class TrainSetWagon extends BaseEntity {
  @Column({ name: 'train_set_id', type: 'uuid' })
  trainSetId!: string;

  @ManyToOne(() => TrainSet, (trainSet) => trainSet.wagons, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'train_set_id' })
  trainSet?: TrainSet;

  @Column({ name: 'wagon_type_id', type: 'uuid' })
  wagonTypeId!: string;

  @Column({ name: 'physical_wagon_id', type: 'uuid', nullable: true })
  physicalWagonId!: string | null;

  @ManyToOne(() => Wagon, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'physical_wagon_id' })
  physicalWagon?: Wagon | null;

  @ManyToOne(() => WagonType, (wagonType) => wagonType.trainSetWagons)
  @JoinColumn({ name: 'wagon_type_id' })
  wagonType?: WagonType;

  @Column({ name: 'sequence_no', type: 'int' })
  sequenceNo!: number;

  @Column({ name: 'capacity_tons', type: 'numeric', precision: 10, scale: 3 })
  capacityTons!: number;

  @Column({ name: 'length_meters', type: 'numeric', precision: 10, scale: 3 })
  lengthMeters!: number;

  @Column({ name: 'assigned_weight_tons', type: 'numeric', precision: 10, scale: 3, default: 0 })
  assignedWeightTons!: number;

  @Column({ name: 'status', type: 'varchar', length: 20, default: 'PLANNED' })
  status!: string;

  @OneToMany(() => WagonBookingAllocation, (allocation) => allocation.trainSetWagon)
  allocations?: WagonBookingAllocation[];
}
