import { Injectable } from '@nestjs/common';
import { UpdateReconciliationManager } from './managers/update-reconciliation.manager';
import { ConfirmReconciliationManager } from './managers/confirm-reconciliation.manager';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { BatchResult } from 'src/core/response/domain/ok-response.interface';
import { BatchConfirmReconciliationManager } from './managers/batch-confirm-reconciliation.manager';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { CancelReconciliationManager } from './managers/cancel-reconciliation.manager';
import { BatchCancelReconciliationManager } from './managers/batch-cancel-reconciliation.manager';
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { RecapReconciliationManager } from './managers/recap-reconciliation.manager';
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
import { RecapReconciliationDto } from '../../infrastructure/dto/recap.dto';

@Injectable()
export class ReconciliationDataOrchestrator {
  constructor(
    private updateManager: UpdateReconciliationManager,
    private confirmManager: ConfirmReconciliationManager,
    private cancelManager: CancelReconciliationManager,
    private batchConfirmManager: BatchConfirmReconciliationManager,
    private batchCancelManager: BatchCancelReconciliationManager,
    private recapManager: RecapReconciliationManager,
    private serviceData: TransactionDataService,
  ) {}

  async update(dataId, data): Promise<TransactionEntity> {
    this.updateManager.setData(dataId, data);
    this.updateManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
    await this.updateManager.execute();
    return this.updateManager.getResult();
  }

  async recap(body: RecapReconciliationDto) {
    const data = new TransactionModel();
    this.recapManager.setData(data);
    this.recapManager.setBodyFilter(body);
    this.recapManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
    await this.recapManager.execute();
    return this.recapManager.getResult();
  }

  async confirm(dataId): Promise<string> {
    this.confirmManager.setData(dataId, STATUS.CONFIRMED);
    this.confirmManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
    await this.confirmManager.execute();
    return this.confirmManager.getResult();
  }

  async batchConfirm(dataIds: string[]): Promise<BatchResult> {
    this.batchConfirmManager.setData(dataIds, STATUS.CONFIRMED);
    this.batchConfirmManager.setService(
      this.serviceData,
      TABLE_NAME.TRANSACTION,
    );
    await this.batchConfirmManager.execute();
    return this.batchConfirmManager.getResult();
  }

  async cancel(dataId, body): Promise<string> {
    this.cancelManager.setData(dataId, STATUS.REJECTED);
    this.cancelManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
    this.cancelManager.setCustomBodyRequest(body);
    await this.cancelManager.execute();
    return this.cancelManager.getResult();
  }

  async batchCancel(dataIds: string[]): Promise<BatchResult> {
    this.batchCancelManager.setData(dataIds, STATUS.REJECTED);
    this.batchCancelManager.setService(
      this.serviceData,
      TABLE_NAME.TRANSACTION,
    );
    await this.batchCancelManager.execute();
    return this.batchCancelManager.getResult();
  }
}
