import generatedRoutes from 'virtual:generated-pages';
import type { ActionTree } from 'vuex';
import type { RouteRecordRaw } from 'vue-router';
import type { Role, UserState } from './typing';
import type { RootState } from '@/store/root-state';
import {
  RESET_CURRENT_USER,
  SET_INFO,
  SET_ROUTERS,
  SET_TOKEN,
  SET_ROUTE_AUTH_DATA,
} from './mutations';
import type { LoginParams } from '@/api/platform/user/login';
import { USER_INFO_KEY } from '@/store/mutation-type';
import {
  postAccountLogin,
  getCurrentUser,
  postLogout,
  getProjectRoutes,
  getPermissionData,
} from '@/api/platform/user/login';
import { default as router, routes } from '@/router';
//import { filterMenu } from '@/utils/menu-util';
import { changeMenu, loadStaticRoutes } from '@/utils/menu-util';
import { useAuthRouter } from '@/utils/authority';
import { generatorDynamicRouter } from '@/router/generator-routers';
// import type { MenuDataItem } from '@/router/typing';
import { commonApi } from '@/api/commonApi';
import { message } from '@crami/ui';
import ls from '@/utils/local-storage';
import { useHttp } from '@crami/http';

import Layout from '@/layouts/index.vue';
//多语言
//import { defineAsyncComponent, h } from 'vue';
//import RouteView from '@/layouts/route-view.vue';
// import { ALL_CONFIG } from '@/utils/commMethods';
import { getDynamicLocale } from '@/utils/localeUtils';
import { computed } from 'vue';
// import store from '@/store/index';

import { SET_PREPARED_SOCKET } from '@/store/modules/global/index';
import { closeSocket } from '@/api/message/socketManagement/socket';

// TODO:导入写死的导航信息
import { menuResult, permissionResult } from './menu';

export const LOGIN = 'LOGIN';
export const LOGOUT = 'LOGOUT';
export const GET_INFO = 'GET_INFO';
export const GENERATE_ROUTES = 'GenerateRoutes';
export const GENERATE_ROUTES_DYNAMIC = '';

// 查找第一个导航，解决第一个菜单是多级导航的问题
const getRedirect = allowRoutes => {
  if (allowRoutes.length > 0) {
    if (!allowRoutes[0].children || allowRoutes[0].children.length == 0) {
      return allowRoutes[0].path;
    } else {
      return getRedirect(allowRoutes[0].children);
    }
  } else {
    return '';
  }
};

// 整合导航权限判断后的路由载入处理方法
const addRoute = (allowRoutes, commit, resolve) => {
  const route = {
    path: '/',
    name: 'index',
    // redirect: allowRoutes.length > 0 ? allowRoutes[0].path : '',
    redirect: getRedirect(allowRoutes),
    component: Layout,
    children: allowRoutes,
  };
  router.addRoute(route);
  commit(SET_ROUTERS, allowRoutes);
  resolve(allowRoutes);
};

// ProjectCode需要请求接口获取
const getProjectCode = async () => {
  // const request = await useHttp({
  //   url: '/api/studio-cache/project/getProject',
  //   method: 'post',
  // });
  const request = {
    code: 200,
    msg: 'PLMBASE',
  };
  return request;
};

const GetQueryString = (name: string) => {
  const reg = new RegExp('(?<=(?:^|&|\\?)' + name + '=)([^&]*)(?=(&|$))', 'g');
  return window.location.search.match(reg)?.[0];
};

export const actions: ActionTree<UserState, RootState> = {
  [LOGIN]({ commit }, info: LoginParams) {
    return new Promise((resolve, reject) => {
      // call ajax
      postAccountLogin(info)
        .then(res => {
          //修改TD 454
          if (res.code == 200) {
            commit(SET_TOKEN, res.data.access_token);
            resolve(res);
          } else {
            reject(res);
          }
        })
        .catch(error => {
          reject(error);
        });
    });
  },
  [GET_INFO]({ commit }) {
    return new Promise((resolve, reject) => {
      const userInfoParams: any = {};
      const orgId = localStorage.getItem('org_data');
      if (orgId !== 'undefined') {
        userInfoParams['orgId'] = orgId;
      }
      getCurrentUser(userInfoParams)
        .then((res: any) => {
          if (res.code == 200) {
            res.data.userId = res.data.user_id;
            // TODO: project改成远程获取，写在这里是权宜之计，后期需要优化
            //jjf临时修改
            // getProjectCode().then((resProject: any) => {
            //   if (resProject.code == 200) {
            //     res.data.projectCode = resProject.msg;
            //   }
              commit(SET_INFO, res.data);
            //   // 增加多语言部分的代码
              getDynamicLocale();
              resolve(res);
            // });

            // TODO:
            //更新store的值
            // const systemLocale = computed(
            //   () => store.getters['app/systemInfo'].DP_DEFAULT_LANGUAGE,
            // );
            // store.dispatch('app/SET_LANG', res.data.lang ? res.data.lang : systemLocale.value);
            // //读取系统设置的时区
            // const systemTimeZone = computed(
            //   () => store.getters['app/systemInfo'].DP_DEFAULT_TIME_ZONE,
            // );
            //本地存储更改多时区防止个人设置没有值的时候取不到值
            localStorage.setItem(
              'TIME_ZONE',
              res.data.TIME_ZONE ? res.data.TIME_ZONE : systemTimeZone.value,
            );
            //更改字段写法给组件使用
            localStorage.setItem(
              'timeZone',
              res.data.TIME_ZONE ? res.data.TIME_ZONE : systemTimeZone.value,
            );
          } else {
            // 当前用户信息获取失败取缓存数据更新store
            const infoData = ls.get(USER_INFO_KEY) ? JSON.parse(ls.get(USER_INFO_KEY)) : {};
            commit(SET_INFO, infoData);
            resolve({ data: infoData });
            message.error(res.msg ? res.msg : '服务异常');
          }
        })
        .catch(err => {
          // 获取登录用户信息后，直接清理掉当前 token 并强制让流程走到登录页
          // commit(SET_TOKEN, null);
          message.error('服务异常');
          reject(err);
        });

      // 设置projectCode
      //jjf临时修改
      // getProjectCode().then((res: any) => {
      //   if (res.code == 200) {
      //     localStorage.setItem('projectCode', res.msg);
      //   }
      // });
    });
  },
  // 从路由表构建路由（前端对比后端权限字段过滤静态路由表）
  [GENERATE_ROUTES]({ commit }, info = {}) {
    const userId = GetQueryString('userId');

    return new Promise<RouteRecordRaw[]>((resolve, reject) => {
      // 修改这里可以进行接口返回的对象结构进行改变
      // 亦或是去掉 info.role 使用别的属性替代
      // 任何方案都可以，只需要将最后拼接构建好的路由数组使用
      // router.addRoute() 添加到当前运行时的路由中即可
      getProjectRoutes({
        type: 'nav',
        ...commonApi().studioCache.getByProjectAndType.params,
        userId,
        // project: localStorage.getItem('productLine'),
        // project: ALL_CONFIG.project,
      })
        .then((res: any) => {
          // TODO: 替换掉请求的参数
          res = menuResult;
          const result = res.code === 200 ? res.data : [];
          loadStaticRoutes(generatedRoutes);
          let allowRoutes = changeMenu(result);
          const orgId = window.localStorage.getItem('org_data') || '';

          if (info?.user_id) {
            // 如果获取用户信息成功，进行权限校验
            getPermissionData({
              lang: info?.lang,
              objectId: info?.user_id,
              companyId: info?.companyId,
              connect: info?.connect,
              userType: info?.user_type,
              userName: info?.user_name,
              orgId: orgId,
              permissionType: 'PC',
              // projectCode: localStorage.getItem('projectCode'),
              ...commonApi().studioCache.getByProjectAndType.params,
              userId,
            })
              .then(res => {
                // TODO: 替换掉权限数据
                res = permissionResult;
                // TODO: 暂时去掉权限  res.data?.nodeList?.length
                if (res.code == 200 && res.data?.nodeList) {
                  // 进行导航权限校验
                  const AuthNavRoutes = useAuthRouter(allowRoutes, res.data?.nodeList) || [];
                  allowRoutes = [...routes, ...AuthNavRoutes];            
                  if (AuthNavRoutes.length == 0) {
                    router.push('/nonav');
                    return;
                  }
                  //将所有权限数据存储到store，方便后面对menu做权限处理
                  commit(SET_ROUTE_AUTH_DATA, {
                    nodeList: res.data?.nodeList,
                    viewerNodeList: res.data?.viewerNodeList,
                  });
                  // const usersPermissions = [];
                  // res.data?.nodeList.forEach(element => {
                  //   usersPermissions.push(element.key);
                  // });
                  // window.localStorage.setItem('usersPermissions', JSON.stringify(usersPermissions));
                } else {
                  // 无导航数据只展示默认导航
                  allowRoutes = routes;
                  if (allowRoutes.length == 0) {
                    router.push('/nonav');
                    return;
                  }
                }
                addRoute(allowRoutes, commit, resolve);
              })
              .catch(() => {
                // 权限接口获取失败只展示默认导航数据
                allowRoutes = routes;
                addRoute(allowRoutes, commit, resolve);
              })
              .finally(() => {
                // 配置完权限后初始化websocket
                // store.commit(`global/${SET_PREPARED_SOCKET}`, true);
              });
          } else {
            // 如果用户信息接口成功，但是无用户id展示默认路由权限
            allowRoutes = routes;
            addRoute(allowRoutes, commit, resolve);
          }
        })
        .catch(err => {
          // 获取登录用户信息后，直接清理掉当前 token 并强制让流程走到登录页
          commit(SET_TOKEN, null);
          reject(err);
        });
    });
  },
  // 从后端获取路由表结构体，并构建前端路由
  [GENERATE_ROUTES_DYNAMIC]({ commit }) {

    return new Promise<RouteRecordRaw>(resolve => {
      generatorDynamicRouter()
        .then((routes: RouteRecordRaw) => {
          const allowRoutes = routes.children || [];
          // 添加到路由表
          router.addRoute(routes);
          commit(SET_ROUTERS, allowRoutes);
          resolve(routes);
        })
        .catch(err => {
          console.error('generatorDynamicRouter', err);
        });
    });
  },
  [LOGOUT]({ commit }, isClear) {
    return new Promise<void>(resolve => {
      postLogout(isClear)
        .then(result => {
          if (result.code == 200) {
            closeSocket();
            if (isClear) {
              commit(SET_TOKEN, null);
            }
            commit(RESET_CURRENT_USER);
          }
          //  else {
          //   commit(SET_TOKEN, null);
          //   window.localStorage.clear();
          //   window.sessionStorage.clear();
          // }
          resolve(result);
        })
        .finally(() => {
          commit(RESET_CURRENT_USER);
          resolve();
        });
    });
  },
};
