import { Injectable } from '@nestjs/common';
import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager';
import { UserPrivilegeConfigurationEntity } from '../../../entities/user-privilege-configuration.entity';
import { SelectQueryBuilder } from 'typeorm';
import {
  Param,
  RelationParam,
} from 'src/core/modules/domain/entities/base-filter.entity';
import { ORDER_TYPE } from 'src/core/strings/constants/base.constants';
import { UserPrivilegeConfigurationHelper } from '../helpers/generate-user-privilege-configuration.helper';
import { PrivilegeAction } from 'src/core/strings/constants/privilege.constants';

@Injectable()
export class IndexUserPrivilegeConfigurationManager extends BaseIndexManager<UserPrivilegeConfigurationEntity> {
  async prepareData(): Promise<void> {
    Object.assign(this.filterParam, {
      order_by: this.filterParam.order_by ?? `${this.tableName}.index`,
      order_type: this.filterParam.order_by ?? ORDER_TYPE.ASC,
      limit: 100,
    });
    return;
  }

  async beforeProcess(): Promise<void> {
    return;
  }

  async afterProcess(): Promise<void> {
    const configs = UserPrivilegeConfigurationHelper.createConfigurations()
      .filter((item) => this.filterParam.modules.includes(item.module))
      ?.map((item) => {
        return {
          ...item,
        };
      });

    configs
      .filter(
        (base) =>
          !this.result.data.some((data) => {
            return base.menu_label == data.menu_label;
          }),
      )
      .map((item) => {
        Object.assign(item, {
          user_privilege_id: this.filterParam.user_privilege_ids?.[0],
        });

        this.result.data.push(item);
      });

    this.result.data = this.result.data
      ?.filter((item) =>
        configs.some((data) => {
          return item.menu_label == data.menu_label;
        }),
      )
      ?.map((item) => {
        const exist = configs.find(
          (config) => config.menu_label == item.menu_label,
        );
        return {
          ...item,
          view: exist.actions.includes(PrivilegeAction.VIEW)
            ? item.view ?? false
            : null,
          cancel: exist.actions.includes(PrivilegeAction.CANCEL)
            ? item.cancel ?? false
            : null,
          confirm: exist.actions.includes(PrivilegeAction.CONFIRM)
            ? item.confirm ?? false
            : null,
          create: exist.actions.includes(PrivilegeAction.CREATE)
            ? item.create ?? false
            : null,
          delete: exist.actions.includes(PrivilegeAction.DELETE)
            ? item.delete ?? false
            : null,
          edit: exist.actions.includes(PrivilegeAction.EDIT)
            ? item.edit ?? false
            : null,
        };
      });

    return;
  }

  get relations(): RelationParam {
    return {
      joinRelations: [],
      selectRelations: [],
      countRelations: [],
    };
  }

  get selects(): string[] {
    return [];
  }

  get specificFilter(): Param[] {
    return [];
  }

  setQueryFilter(
    queryBuilder: SelectQueryBuilder<UserPrivilegeConfigurationEntity>,
  ): SelectQueryBuilder<UserPrivilegeConfigurationEntity> {
    if (this.filterParam.modules) {
      queryBuilder.andWhere('module In (:...modules)', {
        modules: this.filterParam.modules,
      });
    }

    if (this.filterParam.menus) {
      queryBuilder.andWhere('menu In (:...menus)', {
        menus: this.filterParam.menus,
      });
    }

    if (this.filterParam.user_privilege_ids) {
      queryBuilder.andWhere(`user_privilege_id In (:...privilegeIds)`, {
        privilegeIds: this.filterParam.user_privilege_ids,
      });
    }

    return queryBuilder;
  }
}
