import { Inject, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { BaseSysRoleEntity } from '../../entity/sys/role';
import { BaseSysUserRoleEntity } from '../../entity/sys/user_role';
import * as _ from 'lodash';
import { BaseSysRoleMenuEntity } from '../../entity/sys/role_menu';
import { BaseSysRoleToolEntity } from '../../entity/sys/role_tool';
import { BaseSysRoleDepartmentEntity } from '../../entity/sys/role_department';
import { BaseSysPermsService } from './perms';
import { Brackets } from 'typeorm';
import { BaseSysRoleAtlasEntity } from '../../entity/sys/role_atlas';

/**
 * 角色
 */
@Provide()
export class BaseSysRoleService extends BaseService {
  @InjectEntityModel(BaseSysRoleEntity)
  baseSysRoleEntity: Repository<BaseSysRoleEntity>;

  @InjectEntityModel(BaseSysUserRoleEntity)
  baseSysUserRoleEntity: Repository<BaseSysUserRoleEntity>;

  @InjectEntityModel(BaseSysRoleMenuEntity)
  baseSysRoleMenuEntity: Repository<BaseSysRoleMenuEntity>;

  @InjectEntityModel(BaseSysRoleToolEntity)
  baseSysRoleToolEntity: Repository<BaseSysRoleToolEntity>;

  @InjectEntityModel(BaseSysRoleAtlasEntity)
  baseSysRoleAtlasEntity: Repository<BaseSysRoleAtlasEntity>;

  @InjectEntityModel(BaseSysRoleDepartmentEntity)
  baseSysRoleDepartmentEntity: Repository<BaseSysRoleDepartmentEntity>;

  @Inject()
  baseSysPermsService: BaseSysPermsService;

  @Inject()
  ctx;

  /**
   * 根据用户ID获得所有用户角色
   * @param userId
   */
  async getByUser(userId: number): Promise<number[]> {
    const userRole = await this.baseSysUserRoleEntity.findBy({ userId });
    if (!_.isEmpty(userRole)) {
      return userRole.map(e => {
        return e.roleId;
      });
    }
    return [];
  }

  /**
   *
   * @param param
   */
  async modifyAfter(param) {
    if (param.id) {
      if (param.optionsS === '' || param.optionsS === undefined) {
        param.optionsS = null;
      } else {
        param.optionsS = JSON.parse(param.optionsS);
      }
      this.baseSysRoleEntity.save(param);
      this.updatePerms(
        param.id,
        param.menuIdList,
        param.toolIdList,
        param.departmentIdList,
        param.atlasIdList
      );
    }
  }

  /**
   * 更新权限
   * @param roleId
   * @param menuIdList
   * @param departmentIds
   */
  async updatePerms(
    roleId,
    menuIdList?,
    toolIdList?,
    departmentIds = [],
    atlasIdList?
  ) {
    // 更新菜单权限
    await this.baseSysRoleMenuEntity.delete({ roleId });
    for (const e of menuIdList) {
      await this.baseSysRoleMenuEntity.save({ roleId, menuId: e });
    }
    // 更新工具权限
    await this.baseSysRoleToolEntity.delete({ roleId });
    for (const e of toolIdList) {
      await this.baseSysRoleToolEntity.save({ roleId, toolId: e });
    }
    // 更新部门权限
    await this.baseSysRoleDepartmentEntity.delete({ roleId });
    for (const departmentId of departmentIds) {
      await this.baseSysRoleDepartmentEntity.save({ roleId, departmentId });
    }
    // 更新图集权限
    await this.baseSysRoleAtlasEntity.delete({ roleId });
    for (const e of atlasIdList) {
      await this.baseSysRoleAtlasEntity.save({ roleId, atlasId: e });
    }
    // 刷新权限
    const userRoles = await this.baseSysUserRoleEntity.findBy({ roleId });
    for (const userRole of userRoles) {
      await this.baseSysPermsService.refreshPerms(userRole.userId);
    }
  }

  /**
   * 角色信息
   * @param id
   */
  async info(id) {
    const info = await this.baseSysRoleEntity.findOneBy({ id });
    if (info) {
      const menus = await this.baseSysRoleMenuEntity.findBy(
        id !== 1 ? { roleId: id } : {}
      );
      const menuIdList = menus.map(e => {
        return parseInt(e.menuId + '');
      });
      const tools = await this.baseSysRoleToolEntity.findBy(
        id !== 1 ? { roleId: id } : {}
      );
      const toolIdList = tools.map(e => {
        return parseInt(e.toolId + '');
      });
      const departments = await this.baseSysRoleDepartmentEntity.findBy(
        id !== 1 ? { roleId: id } : {}
      );
      const departmentIdList = departments.map(e => {
        return parseInt(e.departmentId + '');
      });
      const atlas = await this.baseSysRoleAtlasEntity.findBy(
        id !== 1 ? { roleId: id } : {}
      );
      const atlasIdList = atlas.map(e => {
        return e.atlasId + '';
      });
      info.optionsS =
        info.optionsS != null ? JSON.stringify(info.optionsS) : '';
      return {
        ...info,
        menuIdList,
        toolIdList,
        departmentIdList,
        atlasIdList,
      };
    }
    return {};
  }

  async list() {
    return this.baseSysRoleEntity
      .createQueryBuilder()
      .where(
        new Brackets(qb => {
          qb.where('id !=:id', { id: 1 }); // 超级管理员的角色不展示
          // 如果不是超管，只能看到自己新建的或者自己有的角色
          if (this.ctx.admin.username !== 'admin') {
            qb.andWhere('("userId"=:userId or id = ANY (:roleId))', {
              userId: this.ctx.admin.userId,
              roleId: this.ctx.admin.roleIds,
            });
          }
        })
      )
      .getMany();
  }
}
