import { Injectable } from '@nestjs/common';
import { DataSource } from 'typeorm';

import { WarehouseInventory } from './entities/warehouse-inventory.entity';

/**
 * READ-ONLY bridge that exposes warehouse inventory to the Train Scheduling
 * domain. It only reads warehouse data — it never assigns wagons, creates or
 * mutates schedules, and is intentionally NOT imported by the scheduling module.
 */
@Injectable()
export class WarehouseSchedulingAdapterService {
  constructor(private readonly dataSource: DataSource) {}

  private get repo() {
    return this.dataSource.getRepository(WarehouseInventory);
  }

  getReadyForLoadingInventory(): Promise<WarehouseInventory[]> {
    return this.repo.find({
      where: { status: 'READY_FOR_LOADING' },
      relations: { warehouse: true, yard: true, zone: true },
      order: { readyForLoadingAt: 'ASC' },
    });
  }

  getReservedInventory(): Promise<WarehouseInventory[]> {
    return this.repo.find({
      where: { status: 'RESERVED' },
      relations: { warehouse: true, yard: true, zone: true },
      order: { reservedAt: 'ASC' },
    });
  }

  getInventoryByBooking(bookingId: string): Promise<WarehouseInventory[]> {
    return this.repo.find({
      where: { bookingId },
      relations: { warehouse: true, yard: true, zone: true },
      order: { createdAt: 'DESC' },
    });
  }

  /**
   * Inventory whose origin booking runs on the given route. Best-effort, read-only:
   * matches the route's origin/destination yards against the booking's yards.
   */
  async getInventoryByRoute(routeId: string): Promise<WarehouseInventory[]> {
    return this.repo
      .createQueryBuilder('inv')
      .leftJoinAndSelect('inv.warehouse', 'warehouse')
      .leftJoinAndSelect('inv.yard', 'yard')
      .leftJoinAndSelect('inv.zone', 'zone')
      .innerJoin('freight.bookings', 'booking', 'booking.id = inv.booking_id')
      .innerJoin(
        'freight.routes',
        'route',
        'route.id = :routeId AND (route.origin_yard_id = booking.origin_yard_id OR route.destination_yard_id = booking.destination_yard_id)',
        { routeId },
      )
      .orderBy('inv.created_at', 'DESC')
      .getMany();
  }
}
