import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ClsService } from 'nestjs-cls';
import { TenantAwareRepository } from '../../../common/repositories/tenant-aware.repository';
import { BookingEntity } from '../../../entities/booking.entity';

@Injectable()
export class BookingRepository extends TenantAwareRepository<BookingEntity> {
  /** Public TypeORM repo handle for advanced querybuilder use inside the service. */
  public readonly ormRepo: Repository<BookingEntity>;

  constructor(
    @InjectRepository(BookingEntity) repo: Repository<BookingEntity>,
    cls: ClsService,
  ) {
    super(repo, cls);
    this.ormRepo = repo;
  }

  async findByIdWithRelations(id: string): Promise<BookingEntity | null> {
    const tenantId = this.getTenantId();
    const booking = await this.repo.findOne({
      where: { id, tenant_id: tenantId, is_deleted: false } as any,
      relations: [
        'query', 'query.destination', 'query.destination.currency', 'query.source', 'query.currency',
        'quote', 'quote.selling_currency',
        'selling_currency',
        'hotel_items', 'hotel_items.hotel',
        'transport_items', 'transport_items.transport_service', 'transport_items.driver', 'transport_items.vehicle', 'transport_items.supplier',
        'activity_items', 'activity_items.activity', 'activity_items.ticket',
        'special_items',
      ],
    });

    if (booking) {
      if (booking.hotel_items) booking.hotel_items = booking.hotel_items.filter(i => !i.is_deleted).sort((a, b) => (a.check_in_date || '').localeCompare(b.check_in_date || ''));
      if (booking.transport_items) booking.transport_items = booking.transport_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
      if (booking.activity_items) booking.activity_items = booking.activity_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
      if (booking.special_items) booking.special_items = booking.special_items.filter(i => !i.is_deleted).sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0));
    }

    return booking;
  }

  async getNextBookingNumber(): Promise<string> {
    const tenantId = this.getTenantId();
    const count = await this.repo
      .createQueryBuilder('b')
      .where('b.tenant_id = :tenantId', { tenantId })
      .getCount();
    return `BK-${String(count + 1).padStart(3, '0')}`;
  }
}
