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

import { Booking } from '../../bookings/entities/booking.entity';
import { Vehicle } from '../../vehicles/entities/vehicle.entity';
import { LastMileContainerAllocation } from './last-mile-container-allocation.entity';
import { LastMileVehicleAssignment } from './last-mile-vehicle-assignment.entity';

export const LAST_MILE_STATUSES = [
  'PAYMENT_PENDING',
  'READY_TO_TRANSIT',
  'IN_TRANSIT',
  'DELIVERED',
] as const;

export type LastMileStatus = (typeof LAST_MILE_STATUSES)[number];

@Entity({ name: 'last_mile', schema: 'freight' })
@Index(['bookingId'])
@Index(['status'])
@Index(['vehicleId'])
export class LastMile extends BaseEntity {
  @Column({ name: 'booking_id', type: 'uuid' })
  bookingId!: string;

  @ManyToOne(() => Booking, { nullable: false, eager: false })
  @JoinColumn({ name: 'booking_id' })
  booking?: Booking;

  @Column({ name: 'status', type: 'varchar', length: 30, default: 'PAYMENT_PENDING' })
  status!: LastMileStatus;

  // Truck-detention window. arrivedAt = vehicle reached destination (IN_TRANSIT);
  // deliveredAt = cargo cleared / vehicle returned (DELIVERED). Detention accrues
  // between them beyond the rule's grace hours (default 3h), per truck per day.
  @Column({ name: 'arrived_at', type: 'timestamptz', nullable: true })
  arrivedAt?: Date | null;

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

  @Column({ name: 'advanced_payment', type: 'numeric', precision: 14, scale: 2, default: 0 })
  advancedPayment!: number;

  @Column({ name: 'remaining_payment', type: 'numeric', precision: 14, scale: 2, default: 0 })
  remainingPayment!: number;

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

  // TODO: uncomment after migration creates column
  // @Column({ type: 'boolean', default: false })
  // isPostPaymentCompleted!: boolean;

  @Column({ name: 'estimated_km', type: 'numeric', precision: 10, scale: 2, nullable: true })
  estimatedKm?: number | null;

  @Column({ name: 'exact_km', type: 'numeric', precision: 10, scale: 2, nullable: true })
  exactKm?: number | null;

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

  @ManyToOne(() => Vehicle, { nullable: true, eager: false })
  @JoinColumn({ name: 'vehicle_id' })
  vehicle?: Vehicle | null;

  @OneToMany(() => LastMileContainerAllocation, (ca) => ca.lastMile)
  containerAllocations?: LastMileContainerAllocation[];

  @OneToMany(() => LastMileVehicleAssignment, (va) => va.lastMile)
  vehicleAssignments?: LastMileVehicleAssignment[];

  // ── Proof of delivery (captured by the EDR driver on completion) ──────────
  @Column({ name: 'pod_recipient_name', type: 'varchar', length: 160, nullable: true })
  podRecipientName?: string | null;

  /** File id of the recipient's captured signature (PNG). */
  @Column({ name: 'pod_signature_file_id', type: 'uuid', nullable: true })
  podSignatureFileId?: string | null;

  /** File ids of the delivery proof photos. */
  @Column({ name: 'pod_photo_file_ids', type: 'text', array: true, default: '{}' })
  podPhotoFileIds!: string[];

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

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