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

import { Contract } from './contract.entity';

/**
 * A customer's request to ship under a GENERAL customs (Path B) contract. The
 * customer cannot book directly; they submit the date + quantities here, Global
 * Logistics reviews the queue, then creates the booking on their behalf — after
 * which per-booking customs clearance begins. ONE_TIME contracts do not use this
 * (they keep contract-level clearance). See plan: per-booking clearance.
 */
@Entity({ schema: 'freight', name: 'booking_requests' })
@Index(['contractId'])
@Index(['status'])
@Index(['contractId', 'status'])
export class BookingRequest extends BaseEntity {
  @Column({ name: 'reference', type: 'varchar', length: 40, default: '' })
  reference!: string;

  @Column({ name: 'contract_id', type: 'uuid' })
  contractId!: string;

  @ManyToOne(() => Contract, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'contract_id' })
  contract?: Contract;

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

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

  /** Customer's preferred shipment day — informational; GL sets the binding date. */
  @Column({ name: 'scheduled_date', type: 'timestamptz', nullable: true })
  scheduledDate?: Date | null;

  @Column({ name: 'status', type: 'varchar', length: 16, default: 'PENDING' })
  status!: Freight.BookingRequestStatus;

  /** Requested quantities (container lines or one bulk line) — no per-unit data. */
  @Column({ name: 'requested_lines', type: 'jsonb', default: () => "'{}'::jsonb" })
  requestedLines!: Freight.RequestedShipmentLines;

  /**
   * Billing currency the customer chose for this shipment. The contract quotes
   * in USD; on a customs contract GL creates the booking, so this is where the
   * customer states which currency to be invoiced in.
   */
  @Column({ name: 'payment_currency', type: 'varchar', length: 5, nullable: true })
  paymentCurrency?: string | null;

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

  /** Set when GL accepts the request and creates the booking. */
  @Column({ name: 'created_booking_id', type: 'uuid', nullable: true })
  createdBookingId?: string | null;

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

  @Column({ name: 'reviewed_at', type: 'timestamptz', nullable: true })
  reviewedAt?: Date | null;

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