import { FindOneOptions, Repository, SelectQueryBuilder } from 'typeorm';
import { BaseFilterEntity } from '../../domain/entities/base-filter.entity';
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';

export abstract class BaseReadService<Entity> {
  constructor(private repository: Repository<Entity>) {}

  getRepository(): Repository<Entity> {
    return this.repository;
  }

  async getIndex(
    queryBuilder: SelectQueryBuilder<Entity>,
    params: BaseFilterEntity,
  ): Promise<PaginationResponse<Entity>> {
    const limit = params.limit ?? 10;
    const page = params.page ?? 1;
    const [data, total] = await queryBuilder
      .take(+limit)
      .skip(+limit * +page - +limit)
      .getManyAndCount();

    return {
      data,
      total,
    };
  }

  async getOneByOptions(findOneOptions): Promise<Entity> {
    return await this.repository.findOne(findOneOptions);
  }

  async getOneOrFailByOptions(
    findOneOptions: FindOneOptions<Entity>,
  ): Promise<Entity> {
    return await this.repository.findOneOrFail(findOneOptions);
  }

  async getManyByOptions(findManyOptions): Promise<Entity[]> {
    return await this.repository.find(findManyOptions);
  }
}
