import { HttpStatus, UnprocessableEntityException } from '@nestjs/common';
import { BaseManager } from '../base.manager';
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
import { OPERATION } from 'src/core/strings/constants/base.constants';

export abstract class BaseDeleteManager<Entity> extends BaseManager {
  protected dataId: string;
  protected result: Entity;
  abstract get entityTarget(): any;

  setData(id: string): void {
    this.dataId = id;
  }

  async prepareData(): Promise<void> {
    this.data = await this.dataService.getOneByOptions({
      where: {
        id: this.dataId,
      },
    });

    if (!this.data)
      throw new UnprocessableEntityException({
        statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
        message: `Gagal! Data denga id ${this.dataId} tidak ditemukan`,
        error: 'Unprocessable Entity',
      });

    return;
  }

  async process(): Promise<void> {
    await new ValidateRelationHelper(
      this.dataId,
      this.dataService,
      this.validateRelations,
      this.tableName,
    ).execute();

    await this.dataService.deleteById(
      this.queryRunner,
      this.entityTarget,
      this.dataId,
    );

    this.publishEvents();
  }

  abstract getResult(): string;

  async publishEvents() {
    this.eventBus.publish(
      new RecordLog({
        id: this.data['id'],
        old: null,
        data: this.data,
        user: this.user,
        description: `${this.user.name} delete data ${this.tableName}`,
        module: this.tableName,
        op: OPERATION.CREATE,
      }),
    );

    if (!this.eventTopics.length) return;
    for (const topic of this.eventTopics) {
      this.eventBus.publishAll([
        new topic.topic({
          id: topic.data['id'],
          old: this.data,
          data: topic.data,
          user: this.user,
          description: '',
          module: this.tableName,
          op: OPERATION.DELETE,
        }),
      ]);
    }
  }
}
