import { Injectable } from '@nestjs/common';
import { UserPrivilegeConfigurationEntity } from '../../../entities/user-privilege-configuration.entity';
import {
  Param,
  RelationParam,
} from 'src/core/modules/domain/entities/base-filter.entity';
import { BaseIndexManager } from 'src/core/modules/domain/usecase/managers/base-index.manager';
import { ORDER_TYPE } from 'src/core/strings/constants/base.constants';
import { Brackets, SelectQueryBuilder } from 'typeorm';
import { FilterMenuUserPrivilegeConfigurationDto } from 'src/modules/user-related/user-privilege/infrastructure/dto/filter-menu-user-privilege-configuration.dto';
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
import { UserRole } from 'src/modules/user-related/user/constants';
import { UserPrivilegeConfigurationHelper } from '../helpers/generate-user-privilege-configuration.helper';

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

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

  async afterProcess(): Promise<void> {
    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,
      });
    }

    queryBuilder.andWhere('user_privilege_id = :user_privilege_id', {
      user_privilege_id: this.userProvider.user.user_privilege_id,
    });

    queryBuilder.andWhere(
      new Brackets((qb) => {
        qb.where('"view" = :view', { view: true }).orWhere(
          '"create" = :create',
          {
            create: true,
          },
        );
      }),
    );

    return queryBuilder;
  }

  getMenuSuperAdmin(params: FilterMenuUserPrivilegeConfigurationDto) {
    const modules = params?.modules ?? [];
    const menus = params?.menus ?? [];
    let configs = UserPrivilegeConfigurationHelper.createConfigurations();

    if (modules.length > 0) {
      configs = configs.filter((item) => modules.includes(item.module));
    }

    if (menus.length > 0) {
      configs = configs.filter((item) => menus.includes(item.menu));
    }

    const newResult = configs.map((item) => {
      const newItem = item;

      item.actions?.forEach((element) => {
        item[element] = true;
      });

      newItem.actions = undefined;

      const cleanData = Object.entries(newItem)
        .filter(([key, value]) => value !== undefined)
        .reduce((obj, [key, value]) => {
          obj[key] = value;
          return obj;
        }, {});

      return cleanData;
    });

    return newResult as any;
  }

  getResult(): PaginationResponse<UserPrivilegeConfigurationEntity> {
    const role = this.userProvider.user.role;
    const isSuperAdmin = role === UserRole.SUPERADMIN;

    if (isSuperAdmin) {
      return {
        data: this.getMenuSuperAdmin(this.filterParam),
        total: 100,
      };
    }

    return this.result;
  }
}
