import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { ClsService } from 'nestjs-cls';
import { TenantAwareRepository } from '../../../common/repositories/tenant-aware.repository';
import { ServicePaymentCollectionEntity } from '../../../entities/service-payment-collection.entity';

/**
 * TenantAware repository for `service_payment_collections`.
 *
 * All reads are auto-scoped to the caller's tenant. The two custom
 * lookups here are the ones the base API can't express: the
 * "one live requirement per supplier junction" uniqueness check and
 * the per-booking rollup for MD.
 */
@Injectable()
export class ServicePaymentCollectionRepository extends TenantAwareRepository<ServicePaymentCollectionEntity> {
  constructor(
    @InjectRepository(ServicePaymentCollectionEntity)
    repo: Repository<ServicePaymentCollectionEntity>,
    cls: ClsService,
  ) {
    super(repo, cls);
  }

  /** Live (non-deleted, non-cancelled) requirement for a specific
   *  supplier junction row, or null. */
  async findLiveByItemSupplier(
    serviceType: 'TRANSPORT' | 'ACTIVITY' | 'SPECIAL',
    itemSupplierId: string,
  ): Promise<ServicePaymentCollectionEntity | null> {
    const fk =
      serviceType === 'TRANSPORT'
        ? 'transport_item_supplier_id'
        : serviceType === 'ACTIVITY'
          ? 'activity_item_supplier_id'
          : 'special_item_supplier_id';
    return this.findOne({
      where: {
        [fk]: itemSupplierId,
        is_deleted: false,
        status: In(['PENDING', 'COLLECTED']),
      } as any,
    });
  }

  /** All live collection rows for a booking + their eager-loaded
   *  currency. Used by MD Chart and Booking Detail. Ordered by
   *  created_at so the FE renders them in the order they were added. */
  async findAllForBooking(
    bookingId: string,
  ): Promise<ServicePaymentCollectionEntity[]> {
    return this.find({
      where: { booking_id: bookingId, is_deleted: false } as any,
      relations: { currency: true, confirmations: true },
      order: { created_at: 'ASC' },
    });
  }

  /** Detail hydration for a single row — includes confirmations
   *  (all of them, live + voided) so the FE can render history. */
  async findByIdWithDetail(
    id: string,
  ): Promise<ServicePaymentCollectionEntity | null> {
    return this.findOne({
      where: { id } as any,
      relations: {
        currency: true,
        confirmations: true,
        booking: true,
      },
    });
  }
}
