import { Injectable } from '@nestjs/common';
import { CreateItemManager } from './managers/create-item.manager';
import { ItemDataService } from '../../data/services/item-data.service';
import { ItemEntity } from '../entities/item.entity';
import { DeleteItemManager } from './managers/delete-item.manager';
import { UpdateItemManager } from './managers/update-item.manager';
import { BaseDataTransactionOrchestrator } from 'src/core/modules/domain/usecase/orchestrators/base-data-transaction.orchestrator';
import { ActiveItemManager } from './managers/active-item.manager';
import { InactiveItemManager } from './managers/inactive-item.manager';
import { ConfirmItemManager } from './managers/confirm-item.manager';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { BatchResult } from 'src/core/response/domain/ok-response.interface';
import { BatchConfirmItemManager } from './managers/batch-confirm-item.manager';
import { BatchInactiveItemManager } from './managers/batch-inactive-item.manager';
import { BatchActiveItemManager } from './managers/batch-active-item.manager';
import { BatchDeleteItemManager } from './managers/batch-delete-item.manager';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { UpdateItemRatePriceManager } from './managers/update-item-rate-price.manager';
import { ItemRateReadService } from 'src/modules/item-related/item-rate/data/services/item-rate-read.service';

@Injectable()
export class ItemDataOrchestrator extends BaseDataTransactionOrchestrator<ItemEntity> {
  constructor(
    private createManager: CreateItemManager,
    private updateManager: UpdateItemManager,
    private deleteManager: DeleteItemManager,
    private activeManager: ActiveItemManager,
    private confirmManager: ConfirmItemManager,
    private inactiveManager: InactiveItemManager,
    private batchDeleteManager: BatchDeleteItemManager,
    private batchActiveManager: BatchActiveItemManager,
    private batchConfirmManager: BatchConfirmItemManager,
    private updatePriceManager: UpdateItemRatePriceManager,
    private batchInactiveManager: BatchInactiveItemManager,
    private serviceData: ItemDataService,
    private serviceRateData: ItemRateReadService,
  ) {
    super();
  }

  async create(data, tenantId?: string): Promise<ItemEntity> {
    if (tenantId) {
      Object.assign(data, {
        tenant_id: tenantId,
      });
    }

    this.createManager.setData(data);
    this.createManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.createManager.execute();
    return this.createManager.getResult();
  }

  async update(dataId, data, tenantId?: string): Promise<ItemEntity> {
    if (tenantId) {
      Object.assign(data, {
        tenant_id: tenantId,
      });
    }

    this.updateManager.setData(dataId, data);
    this.updateManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.updateManager.execute();
    return this.updateManager.getResult();
  }

  async updatePrice(data): Promise<any[]> {
    this.updatePriceManager.setData(data);
    this.updatePriceManager.setService(this.serviceRateData, TABLE_NAME.ITEM);
    await this.updatePriceManager.execute();
    return this.updatePriceManager.getResult();
  }

  async delete(dataId, tenantId?: string): Promise<string> {
    this.deleteManager.setData(dataId);
    this.deleteManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.deleteManager.execute();
    return this.deleteManager.getResult();
  }

  async batchDelete(
    dataIds: string[],
    tenantId?: string,
  ): Promise<BatchResult> {
    this.batchDeleteManager.setData(dataIds);
    this.batchDeleteManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.batchDeleteManager.execute();
    return this.batchDeleteManager.getResult();
  }

  async active(dataId, tenantId?: string): Promise<string> {
    this.activeManager.setData(dataId, STATUS.ACTIVE);
    this.activeManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.activeManager.execute();
    return this.activeManager.getResult();
  }

  async batchActive(
    dataIds: string[],
    tenantId?: string,
  ): Promise<BatchResult> {
    this.batchActiveManager.setData(dataIds, STATUS.ACTIVE);
    this.batchActiveManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.batchActiveManager.execute();
    return this.batchActiveManager.getResult();
  }

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

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

  async inactive(dataId, tenantId?: string): Promise<string> {
    this.inactiveManager.setData(dataId, STATUS.INACTIVE);
    this.inactiveManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.inactiveManager.execute();
    return this.inactiveManager.getResult();
  }

  async batchInactive(
    dataIds: string[],
    tenantId?: string,
  ): Promise<BatchResult> {
    this.batchInactiveManager.setData(dataIds, STATUS.INACTIVE);
    this.batchInactiveManager.setService(this.serviceData, TABLE_NAME.ITEM);
    await this.batchInactiveManager.execute();
    return this.batchInactiveManager.getResult();
  }
}
