import { BaseRepository } from '@edr/api-common';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { BookingRequest } from './entities/booking-request.entity';

@Injectable()
export class BookingRequestRepository extends BaseRepository<BookingRequest> {
  constructor(
    @InjectRepository(BookingRequest)
    repository: Repository<BookingRequest>,
  ) {
    super(repository);
  }

  /** All requests on a contract, newest first. */
  async findForContract(contractId: string): Promise<BookingRequest[]> {
    return this.repository.find({
      where: { contractId },
      order: { createdAt: 'DESC' },
    });
  }

  /**
   * GL queue: every request across all contracts, newest first. The queue page
   * filters by status client-side (pending work vs accepted/rejected history),
   * and surfaces the customer — so the contract's company rides along.
   */
  async findQueue(): Promise<BookingRequest[]> {
    return this.repository.find({
      order: { createdAt: 'DESC' },
      relations: { contract: { company: true } },
    });
  }

  async findById(id: string): Promise<BookingRequest | null> {
    return this.repository.findOne({
      where: { id },
      // Load the contract with the bits the detail page surfaces: customer
      // (company), service type (mile/customs flags), routes (with yard labels)
      // and cargo scope.
      relations: {
        contract: {
          company: true,
          serviceType: true,
          routes: { originYard: true, destinationYard: true },
          cargoScope: true,
        },
      },
    });
  }

  /**
   * Highest NNNNNN sequence already issued for `SR-…` references (all-time —
   * these are not year-scoped). Includes soft-deleted rows so a cancel/delete
   * can't make the next number reuse an earlier one. A plain row count drifts
   * below the issued sequence after any delete and hands out duplicates.
   */
  async maxReferenceSequence(): Promise<number> {
    const row = await this.repository
      .createQueryBuilder('request')
      .withDeleted()
      .select(
        "COALESCE(MAX(CAST(SUBSTRING(request.reference FROM '[0-9]+$') AS int)), 0)",
        'max',
      )
      .where('request.reference LIKE :prefix', { prefix: 'SR-%' })
      .getRawOne<{ max: string | number | null }>();
    return Number(row?.max ?? 0);
  }
}
