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

import { WagonBookingAllocation } from './entities/wagon-booking-allocation.entity';

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

  private repo(manager?: EntityManager) {
    return manager ? manager.getRepository(WagonBookingAllocation) : this.repository;
  }

  async createMany(
    records: DeepPartial<WagonBookingAllocation>[],
    manager?: EntityManager,
  ): Promise<WagonBookingAllocation[]> {
    if (!records.length) return [];
    const repo = this.repo(manager);
    return repo.save(repo.create(records));
  }

  findByScheduleId(trainScheduleId: string, manager?: EntityManager): Promise<WagonBookingAllocation[]> {
    return this.repo(manager)
      .createQueryBuilder('allocation')
      .innerJoin('allocation.trainSetWagon', 'wagon')
      .innerJoin('wagon.trainSet', 'trainSet')
      .innerJoin('trainSet.trainSchedule', 'schedule')
      .where('schedule.id = :trainScheduleId', { trainScheduleId })
      .leftJoinAndSelect('allocation.booking', 'booking')
      .getMany();
  }

  async deleteByTrainSetId(trainSetId: string, manager?: EntityManager): Promise<string[]> {
    const allocations = await this.repo(manager)
      .createQueryBuilder('allocation')
      .innerJoin('allocation.trainSetWagon', 'wagon')
      .where('wagon.train_set_id = :trainSetId', { trainSetId })
      .select(['allocation.id'])
      .getMany();

    const ids = allocations.map((a) => a.id);
    if (ids.length) {
      await this.repo(manager).delete(ids);
    }
    return ids;
  }
}
