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

import { Yard } from '../../rule-engine/entities/yard.entity';
import { WagonType } from '../../wagon-types/entities/wagon-type.entity';

/**
 * A two-person wagon relocation request. A requester asks for `quantity` wagons
 * of `wagonTypeId` to move from `fromYardId` to `toYardId` — specifying a count
 * only, never the physical wagons. OCC staff later open the PENDING request,
 * hand-pick the actual wagons in the source yard, and execute the transfer
 * (which writes the `wagon_movements` ledger and marks this FULFILLED).
 */
@Entity({ schema: 'freight', name: 'wagon_transfer_requests' })
@Index(['status', 'fromYardId'])
export class WagonTransferRequest extends BaseEntity {
  @Column({ name: 'from_yard_id', type: 'uuid' })
  fromYardId!: string;

  @ManyToOne(() => Yard)
  @JoinColumn({ name: 'from_yard_id' })
  fromYard?: Yard | null;

  @Column({ name: 'to_yard_id', type: 'uuid' })
  toYardId!: string;

  @ManyToOne(() => Yard)
  @JoinColumn({ name: 'to_yard_id' })
  toYard?: Yard | null;

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

  @ManyToOne(() => WagonType)
  @JoinColumn({ name: 'wagon_type_id' })
  wagonType?: WagonType | null;

  /** How many wagons of `wagonTypeId` to move out of `fromYardId`. */
  @Column({ name: 'quantity', type: 'int' })
  quantity!: number;

  /**
   * How many have actually moved so far. OCC sends what the yard can spare,
   * whenever it can — the request stays open until this reaches `quantity` or
   * OCC closes it short.
   */
  @Column({ name: 'fulfilled_quantity', type: 'int', default: 0 })
  fulfilledQuantity!: number;

  @Column({
    name: 'status',
    type: 'varchar',
    length: 20,
    default: WagonTransferRequestStatus.Pending,
  })
  status!: WagonTransferRequestStatus;

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

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

  /** When the LAST transfer against this request ran (not necessarily the full count). */
  @Column({ name: 'fulfilled_at', type: 'timestamptz', nullable: true })
  fulfilledAt?: Date | null;

  /** Set when OCC ended the request with fewer wagons than asked for. */
  @Column({ name: 'closed_short_at', type: 'timestamptz', nullable: true })
  closedShortAt?: Date | null;

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

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

  /**
   * Why the wagons are needed — required for every new request and shown on
   * the OCC queue. Nullable only for rows that predate the requirement.
   */
  @Column({ name: 'reason', type: 'text', nullable: true })
  reason?: string | null;
}
