import { Inject, Injectable, Logger } from '@nestjs/common';
import { UserProvider, UsersSession } from 'src/core/sessions';
import { BLANK_USER } from 'src/core/strings/constants/base.constants';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { RelationParam } from '../entities/base-filter.entity';

@Injectable()
export abstract class BaseReadManager {
  public user: UsersSession;
  public dataService: any;
  public queryBuilder: any;
  protected tableName: TABLE_NAME;
  abstract get relations(): RelationParam;
  abstract get selects(): string[];
  @Inject()
  protected userProvider: UserProvider;

  private readonly baseLog = new Logger(BaseReadManager.name);

  setUser() {
    try {
      this.user = this.userProvider?.user;
    } catch (error) {
      this.user = BLANK_USER;
    }
  }

  setService(dataService, tableName) {
    this.dataService = dataService;
    this.tableName = tableName;
    this.queryBuilder = this.dataService
      .getRepository()
      .createQueryBuilder(this.tableName);
  }

  async execute(): Promise<void> {
    this.baseLog.log(`prepareData`, BaseReadManager.name);
    await this.prepareData();

    this.baseLog.log(`beforeProcess`, BaseReadManager.name);
    await this.beforeProcess();

    this.baseLog.log('process', BaseReadManager.name);
    await this.process();

    this.baseLog.log('afterProcess', BaseReadManager.name);
    await this.afterProcess();
  }

  abstract prepareData(): Promise<void>;

  abstract beforeProcess(): Promise<void>;

  abstract process(): Promise<void>;

  abstract afterProcess(): Promise<void>;
}
