import { BaseEntity } from '@edr/api-common';
import { SchedulingStatus } from '@edr/types';
import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
import { Booking } from '../../bookings/entities/booking.entity';
import { Company } from '../../companies/entities/company.entity';
import { BookingOrderLine } from './booking-order-line.entity';

/**
 * A single drawdown against a general contract. Each order spawns its own
 * ONE_TIME child Booking (the shipment that enters the train scheduling
 * pipeline); this row is the ledger entry linking the contract to that
 * shipment and recording the drawn-down quantities.
 */
@Entity({ schema: 'freight', name: 'booking_orders' })
export class BookingOrder extends BaseEntity {
  @Column({ name: 'reference', type: 'varchar', length: 64, unique: true })
  reference!: string;

  /** The general contract (a Booking with bookingType = GENERAL_CONTRACT). */
  @Column({ name: 'contract_booking_id', type: 'uuid' })
  contractBookingId!: string;

  @ManyToOne(() => Booking)
  @JoinColumn({ name: 'contract_booking_id' })
  contractBooking?: Booking;

  /** The ONE_TIME child shipment booking spawned for this order. */
  @Column({ name: 'booking_id', type: 'uuid', nullable: true })
  bookingId?: string | null;

  @ManyToOne(() => Booking, { nullable: true })
  @JoinColumn({ name: 'booking_id' })
  booking?: Booking | null;

  /** Denormalized from the contract for fast company-scoped filtering. */
  @Column({ name: 'company_id', type: 'uuid', nullable: true })
  companyId?: string | null;

  @ManyToOne(() => Company, { nullable: true })
  @JoinColumn({ name: 'company_id' })
  company?: Company | null;

  /**
   * The contract route line this order drew down (multi-route general contracts).
   * Null for legacy/single-route contracts that have no route lines — the order
   * then uses the contract's own origin/destination.
   */
  @Column({ name: 'route_line_id', type: 'uuid', nullable: true })
  routeLineId?: string | null;

  @Column({ name: 'scheduled_date', type: 'timestamptz' })
  scheduledDate!: Date;

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

  @Column({
    name: 'scheduling_status',
    type: 'varchar',
    length: 30,
    default: SchedulingStatus.NotScheduled,
  })
  schedulingStatus!: string;

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

  @OneToMany(() => BookingOrderLine, (line) => line.order, { cascade: true })
  lines?: BookingOrderLine[];
}
