

import { defineStore } from 'pinia';
import { http } from '/nerv-lib/util/http';
import { stringUtil } from '/nerv-lib/util/string-util';
import { cloneDeep } from 'lodash-es';
import { toRaw } from 'vue';
import { log } from '/nerv-lib/util/log';

export const authorizationService = defineStore({
  id: 'authorizationService',
  /**
   * token   测试用
   * userinfo  用户信息
   * itemMap   权限树
   * @returns
   */
  state(): {
    token: boolean;
    userInfo: any;
    itemMap: any;
    defaultRegion: { value: string; label: string; isDefault: any };
    currentRegion: { value: string; label: string; isDefault: any };
    regionArray: Array<any>;
    ModulesRes: Array<any>;
    permissionMap: Recordable;
    switches: Recordable;
  } {
    return {
      token: false,
      userInfo: {},
      itemMap: {},
      defaultRegion: { label: '', value: '', isDefault: '' },
      currentRegion: { label: '', value: '', isDefault: '' },
      regionArray: [],
      ModulesRes: [],
      permissionMap: {},
      switches: {},
    };
  },
  actions: {
    login() {},
    logout() {
      window.location.href = '/login';
    },
    loadAuthorization() {
      return http.post('/api/passport/passport/objs/Authorization/CheckAuthorization');
    },
    loadModules() {
      return http.get('/api/webui/webui/objs/GetModules');
    },
    loadRegion() {
      return http.get('/api/passport/objs/GetRegionsInfo');
    },
    loadSwitch() {
      return http.get('/api/webui/webui/objs/GetSwitchs');
    },
    getAuthMap() {
      const requestArr = [
        this.loadAuthorization(),
        this.loadModules(),
        this.loadRegion(),
        this.loadSwitch(),
      ];
      return Promise.all(requestArr).then((result) => {
        if (result && result.length >= 2) {
          log.info('权限加载完成');
          const authResponse = result[0];
          const menusResponse = result[1];
          this.ModulesRes = cloneDeep(result[1]);
          result[2] ? this.setRegionInfo(result[2]) : '';
          this.itemMap = this.convertResponse2ItemMap(authResponse, menusResponse);
          this.permissionMap = this.getPermissionMap(authResponse, menusResponse);
          this.switches = result[3]?.switchs;

          log.info('生成权限树', toRaw(this.permissionMap));
        }
      });
    },

    /**
     * 是否有权限
     *
     * @param moduleName 模块名
     *
     * @param subModuleName 子模块名
     *
     * @param operationName 操作名
     *
     * @returns {boolean} true: 有权限, false: 没有权限
     */
    exists(moduleName: string, subModuleName?: string, operationName?: string): boolean {
      /**（1）访问主模块*/
      let key = moduleName;
      if (subModuleName) {
        /**（2）访问子模块*/
        key = key + '_' + subModuleName;
      }
      /**（3）某个具体操作*/
      if (operationName) {
        key = key + '_' + operationName;
      }
      // this.checkAuthMap()
      return this.itemMap[key] != null || this.isAdmin();
    },

    // 递归遍历权限树方法
    traverseMenus(menusItem: any, subMenus: any, itemMap: any, module: any) {
      if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
        menusItem['submenus'].forEach((subMenu: any) => {
          if (subMenu['isGlobalDisplay']) {
            if (!subMenu['isOperation']) {
              // 如果是自定义资源且是操作，就不用按照菜单权限写入
              if (subMenu['operation'] && subMenu['operation']['resource']) {
                const subMenusName = subMenu['operation']['resource'];
                subMenus.push(subMenusName);
                itemMap[module['name'] + '_' + subMenusName] = true;
                if (subMenu['operations'] && subMenu['operations'].length) {
                  subMenu['operations'].forEach((op: any) => {
                    itemMap[module['name'] + '_' + subMenusName + '__' + op['name']] = true;
                    itemMap[
                      module['name'] + '_' + subMenusName + stringUtil.firstToUpper(op['name'])
                    ] = true; //操作对应的页面权限
                  });
                }
              }
            } else {
              // 如果是自定义资源且是操作，如【管理】按钮，将它写入父节点的操作里
              const opName = subMenu?.operation.resource;
              itemMap[module['name'] + '_' + menusItem['name'] + '__' + opName] = true; // xxApp_xxMenus__xxOpName
              itemMap[module['name'] + '_' + menusItem['name'] + stringUtil.firstToUpper(opName)] =
                true; //操作对应的页面权限，如：xxApp_xxMenusXxOpName
            }
            this.traverseMenus(subMenu, subMenus, itemMap, module);
          }
        });
      } else {
        return;
      }
    },
    //处理权限树
    convertResponse2ItemMap(authResponse: any, menusResponse: any) {
      const itemMap: any = {};
      /** 如果是具有admin权限用户*/
      if (authResponse['accountname'] == 'admin' || authResponse['isAdmin']) {
        itemMap['*'] = '';
        return itemMap;
      }
      /***默认显示的模块或者菜单 如：监控下面的指标监控
       *  先处理默认显示的模块权限，再处理授权的权限,注意顺序
       */
      if (menusResponse instanceof Array) {
        menusResponse.forEach((module) => {
          if (module['isGlobalDisplay']) {
            let menus: Array<any> = [];
            if (itemMap[module['name']] == null) {
              itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
            }
            itemMap[module['name']] = '';
            if (module['menus'] && module['menus'].length > 0) {
              module['menus'].forEach((menusItem: any) => {
                if (menusItem['isGlobalDisplay']) {
                  if (menusItem['isGlobal']) {
                    // 1. 全局开放模块又是独立模块
                    itemMap[menusItem['name']] = '';
                    const globalMenus: Array<any> = [];
                    if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
                      menusItem['submenus'].forEach((subMenu: any) => {
                        if (subMenu['isGlobalDisplay']) {
                          if (subMenu['operation'] && subMenu['operation']['resource']) {
                            const globalMenuName = subMenu['operation']['resource'];
                            globalMenus.push(globalMenuName);
                            itemMap[menusItem['name'] + '_' + globalMenuName] = '';
                            if (subMenu['operations'] && subMenu['operations'].length) {
                              subMenu['operations'].forEach((op: any) => {
                                itemMap[
                                  menusItem['name'] + '_' + globalMenuName + '_' + op['name']
                                ] = '';
                              });
                            }
                          }

                          if (menusItem['isDir']) {
                            itemMap[module['name'] + '_' + subMenu['name']] = true;
                          }
                        }
                      });
                      itemMap[menusItem['name']] = globalMenus;
                    }
                  } else if (menusItem['isDir']) {
                    // 2. 文件夹下的模块
                    const subMenus: Array<any> = [];
                    this.traverseMenus(menusItem, subMenus, itemMap, module);
                    menus = [...menus, ...subMenus];
                  } else {
                    //3. 普通全局开放模块
                    menus.push(menusItem['name']);
                    itemMap[module['name'] + '_' + menusItem['name']] = '';
                    if (menusItem.operations && menusItem.operations.length) {
                      menusItem.operations.forEach((op: any) => {
                        itemMap[module['name'] + '_' + menusItem['name'] + '_' + op['name']] = '';
                      });
                    }
                    // 处理下层菜单
                    const subMenus: Array<any> = [];
                    this.traverseMenus(menusItem, subMenus, itemMap, module);
                    menus = [...menus, ...subMenus];
                  }
                }
              });
            }
            itemMap[module['name']] = menus;
          }
        });
      }
      if (!authResponse) {
        return itemMap;
      }
      const projects = authResponse['projects'];
      if (!projects.length) {
        return itemMap;
      }
      projects.forEach((project: any) => {
        // if (project['projectname'] == 'systemProject') {
        const modules = project['modules'];
        if (!modules.length) {
          return;
        }
        modules.forEach((module: any) => {
          let menus = [];
          if (itemMap[module['name']] == null) {
            itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
          }
          if (!module['resources'].length) {
            return;
          }
          module['resources'].forEach((subModule: any) => {
            menus.push(subModule['name']);
            itemMap[module['name'] + '_' + subModule['name']] = ''; //当该资源在系统项目下，即受角色管理
            itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] = '';
            if (!subModule['operations'].length) {
              return;
            }
            const ops: Array<any> = [];
            subModule['operations'].forEach((op: any) => {
              /**权限合并修改：
               * 1.后端注册权限将查看(detail)和列表(list)权限合并为查看（list）权限后，
               * 2.前端：用户勾选查看（list），即表示有查看列表和详情权限。
               */
              if (op['name'] == subModule['name'] + '_list') {
                op['name'] = subModule['name'] + '_detail';
              }
              itemMap[module['name'] + '_' + subModule['name'] + '_' + op['name']] = '';
              itemMap[
                module['name'] +
                  '_' +
                  subModule['name'] +
                  '_' +
                  project['projectname'] +
                  '_' +
                  op['name']
              ] = '';
              ops.push(op['name']);
            });
            itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
              ops.join(',');
          });
          if (itemMap[module['name']] && itemMap[module['name']] instanceof Array) {
            //如果上个项目在该模块有菜单
            menus.push(...itemMap[module['name']]); //合并
            menus = Array.from(new Set(menus)); //去重
          }
          itemMap[module['name']] = menus;
        });
        // }
      });
      return itemMap;
    },

    //判断是否在当前项目内
    isCurrentApp(app: string) {
      const url = window.location.href;
      const reg = /[http|https]+:\/\/.+?\/([^/]+)/gi;
      let currentApp;
      const result = reg.exec(url);
      if (result != null) {
        currentApp = result[1];
      }
      return currentApp === app;
    },

    getValidFirstMenuName(moduleName: string | number) {
      if (!this.itemMap) {
        return [];
      }
      // let menuName = null;
      const menus: any[] = this.itemMap[moduleName];
      // if(!menus||menus.length==0)return;
      // menuName = menus[0];
      return menus;
    },

    isAdmin() {
      return this.itemMap['*'] != null;
    },

    //设置region信息
    setRegionInfo(response: any) {
      if (response) {
        const item: { label: any; value: any; isDefault: any }[] = [];
        const regions = response['regions'];
        regions.forEach((region: { isDefault: any; name: any; label: any }) => {
          region.isDefault
            ? (this.defaultRegion = {
                label: region.label,
                value: region.name,
                isDefault: region.isDefault,
              })
            : '';
          item.push({
            label: region.label,
            value: region.name,
            isDefault: region.isDefault,
          });
        });
        this.regionArray = item;
      }
    },

    setCurrentRegion(currentRegion: { value: string; label: string; isDefault: any }) {
      this.currentRegion = currentRegion;
    },

    getApp() {
      return ((import.meta.env.VITE_PUBLIC_PATH || '') as string).replace(/\//g, '');
    },

    getPermissionMap(authResponse: any, menusResponse: any) {
      const itemMap: any = {};
      // itemMap['*'] = true;
      // return itemMap;
      /** 如果是具有admin权限用户*/
      if (authResponse['accountname'] == 'admin' || authResponse['isAdmin']) {
        itemMap['*'] = true;
        return itemMap;
      }

      /***默认显示的模块或者菜单 如：监控下面的指标监控
       *  先处理默认显示的模块权限，再处理授权的权限,注意顺序
       */
      if (menusResponse instanceof Array) {
        menusResponse.forEach((module) => {
          if (module['isGlobalDisplay']) {
            let menus: Array<any> = [];
            if (itemMap[module['name']] == null) {
              itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
            }
            itemMap[module['name']] = '';
            if (module['menus'] && module['menus'].length > 0) {
              module['menus'].forEach((menusItem: any) => {
                if (menusItem['isGlobalDisplay']) {
                  if (menusItem['isGlobal']) {
                    //全局开放模块又是独立模块
                    itemMap[menusItem['name']] = '';
                    const globalMenus: Array<any> = [];
                    if (menusItem['submenus'] && menusItem['submenus'].length > 0) {
                      menusItem['submenus'].forEach((subMenu: any) => {
                        if (subMenu['isGlobalDisplay']) {
                          if (subMenu['operation'] && subMenu['operation']['resource']) {
                            const globalMenuName = subMenu['operation']['resource'];
                            globalMenus.push(globalMenuName);
                            itemMap[menusItem['name'] + '_' + globalMenuName] = true;
                            if (subMenu['operations'] && subMenu['operations'].length) {
                              subMenu['operations'].forEach((op: any) => {
                                itemMap[
                                  menusItem['name'] + '_' + globalMenuName + '__' + op['name']
                                ] = true;
                                itemMap[
                                  menusItem['name'] +
                                    '_' +
                                    globalMenuName +
                                    stringUtil.firstToUpper(op['name'])
                                ] = true; //权限对应页面
                              });
                            }
                          }
                        }
                      });
                      itemMap[menusItem['name']] = globalMenus;
                    }
                  } else if (menusItem['isDir']) {
                    // 2. 文件夹下的模块
                    const subMenus: Array<any> = [];
                    this.traverseMenus(menusItem, subMenus, itemMap, module);
                    menus = [...menus, ...subMenus];
                  } else {
                    //3. 普通全局开放模块
                    menus.push(menusItem['name']);
                    itemMap[module['name'] + '_' + menusItem['name']] = true;
                    if (menusItem.operations && menusItem.operations.length) {
                      menusItem.operations.forEach((op: any) => {
                        itemMap[module['name'] + '_' + menusItem['name'] + '__' + op['name']] =
                          true;
                        itemMap[
                          module['name'] +
                            '_' +
                            menusItem['name'] +
                            stringUtil.firstToUpper(op['name'])
                        ] = true; //权限对应页面
                      });
                    }
                    // 处理下层菜单
                    const subMenus: Array<any> = [];
                    this.traverseMenus(menusItem, subMenus, itemMap, module);
                    menus = [...menus, ...subMenus];
                  }
                }
              });
            }
            itemMap[module['name']] = menus;
          }
        });
      }

      if (!authResponse) {
        return itemMap;
      }
      const projects = authResponse['projects'];
      if (!projects.length) {
        return itemMap;
      }
      projects.forEach((project: any) => {
        const modules = project['modules'];
        if (!modules.length) {
          return;
        }
        modules.forEach((module: any) => {
          let menus = [];
          if (itemMap[module['name']] == null) {
            itemMap[module['name']] = ''; //保留上个项目中该模块的菜单信息
          }
          if (!module['resources'].length) {
            return;
          }
          module['resources'].forEach((subModule: any) => {
            menus.push(subModule['name']);
            if (project['projectname'] === 'systemProject') {
              itemMap[module['name'] + '_' + subModule['name']] = 'systemProject'; //当该资源在系统项目下，即受角色管理
            } else {
              itemMap[module['name'] + '_' + subModule['name']] = true; //当该资源在系统项目下，即受角色管理
              itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
                true;
            }
            if (!subModule['operations'].length) {
              return;
            }
            const ops: Array<any> = [];
            subModule['operations'].forEach((op: any) => {
              /**权限合并修改：
               * 1.后端注册权限将查看(detail)和列表(list)权限合并为查看（list）权限后，
               * 2.前端：用户勾选查看（list），即表示有查看列表和详情权限。
               */
              if (op['name'] == 'list') {
                op['name'] = 'detail';
              }
              itemMap[module['name'] + '_' + subModule['name'] + '__' + op['name']] = true;
              itemMap[
                module['name'] + '_' + subModule['name'] + stringUtil.firstToUpper(op['name'])
              ] = true; //权限对应页面
              if (project['projectname'] !== 'systemProject') {
                itemMap[
                  module['name'] +
                    '_' +
                    subModule['name'] +
                    '_' +
                    project['projectname'] +
                    '__' +
                    op['name']
                ] = true;
              }
              ops.push(op['name']);
            });
            if (project['projectname'] !== 'systemProject') {
              itemMap[module['name'] + '_' + subModule['name'] + '_' + project['projectname']] =
                ops.join(',');
            }
          });
          if (itemMap[module['name']] && itemMap[module['name']] instanceof Array) {
            //如果上个项目在该模块有菜单
            menus.push(...itemMap[module['name']]); //合并
            menus = Array.from(new Set(menus)); //去重
          }
          itemMap[module['name']] = menus;
        });
        // }
      });
      return itemMap;
    },
    async checkAuthMap() {
      if (this.ModulesRes.length === 0) {
        await this.getAuthMap();
      }
    },
    checkPermission(
      moduleName: string,
      subModuleName?: string | undefined,
      operationName?: string | undefined,
      projectName?: string | undefined,
    ): boolean {
      if (this.permissionMap['*']) {
        return true;
      }

      let key = moduleName;
      if (!subModuleName) {
        // console.log(1, key);
        return !!this.permissionMap[key];
      }
      key = `${key}_${subModuleName}`;

      if (!projectName) {
        if (operationName) {
          key = `${key}__${operationName}`;
        }


        return !!this.permissionMap[key];
      }
      if (this.permissionMap[key] === 'systemProject') {
        if (operationName) {
          key = `${key}__${operationName}`;
        }
        // console.log(3, key, operationName);

        return !!this.permissionMap[key];
      } else {
        key = `${key}_${projectName}`;
        if (operationName) {
          key = `${key}__${operationName}`;
        }
      
        return !!this.permissionMap[key];
      }
    },
  },
});
