import {
  logout,
  getInfo,
  loginYx,
  getParameterVauleByCode,
  languageSettingListPage,
  getFileServerInfo,
  getLoginConfig,
} from "../../api/user";
import { getToken, setToken, clearToken } from "../../utils/auth";
import router, { resetRouter } from "@base/router";
import { getDispermissions } from "../../api/menu";
import settingConfig from "@/settings";
import storeConfig from "../config/index";

let state, mutations, actions;
let configUtil = {
  logout,
  getInfo,
  loginYx,
  getToken,
  setToken,
  clearToken,
  router,
  resetRouter,
  getDispermissions,
};

state = {
  token: configUtil.getToken(),
  name: "",
  avatar: "",
  introduction: "",
  roles: [],
  dispermissions: [],
  companyInfoId: "",
  companyCode: "",
  loginAccount: "",
  nickName: "",
  userId: "",
  queryCreateInfo: false,
  languageSettings: [],
  isBdAdmin: false,
  userFlag: null,
  fileServerInfo: null,
  loginConfig: null,
  utcTransformOffset: 0,// 时区偏移量，单位：小时
};

mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  SET_INTRODUCTION: (state, introduction) => {
    state.introduction = introduction;
  },
  SET_NAME: (state, name) => {
    state.name = name;
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar;
  },
  SET_ROLES: (state, roles) => {
    state.roles = roles;
  },
  SET_DISPERMISSIONS: (state, dispermissions) => {
    state.dispermissions = dispermissions;
  },
  SET_NICK_NAME: (state, nickName) => {
    state.nickName = nickName;
  },
  SET_LOGIN_ACCOUNT: (state, loginAccount) => {
    state.loginAccount = loginAccount;
  },
  SET_COMPANY_CODE: (state, companyCode) => {
    state.companyCode = companyCode;
  },
  SET_USER_ID: (state, userId) => {
    state.userId = userId;
  },
  SET_QUERY_CREATE_INFO: (state, queryCreateInfo) => {
    state.queryCreateInfo = queryCreateInfo || false;
  },
  SET_LANGUAGE_SETTINGS: (state, languageSettings) => {
    state.languageSettings = languageSettings;
  },
  SET_IS_BD_ADMIN: (state, isBdAdmin) => {
    state.isBdAdmin = isBdAdmin;
  },
  SET_USER_FLAG: (state, userFlag) => {
    state.userFlag = userFlag;
  },
  SET_FILE_SERVER_INFO: (state, fileServerInfo) => {
    state.fileServerInfo = fileServerInfo;
  },
  SET_LOGIN_CONFIG: (state, loginConfig) => {
    state.loginConfig = loginConfig;
  },
  SET_UTC_TRANSFORM_OFFSET: (state, utcTransformOffset) => {
    state.utcTransformOffset = utcTransformOffset;
  },
};

actions = {
  // user login
  login2({ commit, dispatch }, userInfo) {
    const { username, password } = userInfo;
    return new Promise((resolve, reject) => {
      configUtil
        .loginYx({
          data: {
            ...userInfo,
          },
          callback: (res) => {
            if (res.type == "success") {
              var token = res.objx;
              dispatch("addToken", {
                token,
              });
            }
            resolve(res);
          },
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
  addToken({ commit }, opts) {
    return new Promise((resolve, reject) => {
      let token = opts.token;
      commit("SET_TOKEN", token);
      configUtil.setToken(token);
      sessionStorage.setItem(
        "easyweb",
        JSON.stringify({
          token: JSON.stringify({
            access_token: token,
          }),
        })
      );
      resolve(opts);
    });
  },

  // get user info
  getInfo2({ commit, state }) {
    return new Promise((resolve, reject) => {
      configUtil
        .getInfo({
          callback: (response) => {
            if (response) {
              if (response.type == "success") {
                let user = response.objx; //当前用户

                let userFlag = user.flag;
                let userFlagMenuMap = storeConfig?.userFlagMenuMap || {};
                let isBdAdmin = !!(
                  userFlag !== undefined &&
                  userFlag !== null &&
                  !!userFlagMenuMap[userFlag]
                );

                //用户
                commit("SET_ROLES", ["*"]);
                commit("SET_NICK_NAME", user.nickName);
                commit("SET_LOGIN_ACCOUNT", user.loginAccount);
                commit("SET_COMPANY_CODE", user.companyCode);
                commit("SET_USER_ID", user.id);
                commit("SET_IS_BD_ADMIN", isBdAdmin);
                commit("SET_USER_FLAG", user.flag);

                let flag = true;
                let requests = [
                  getDispermissions({
                    success: (res) => {
                      //按钮权限
                      let dispermissions = (res.objx || []).map(function (
                        item
                      ) {
                        return item.menuCode;
                      });
                      commit("SET_DISPERMISSIONS", dispermissions);
                    },
                    fail: (res) => {
                      flag = false;
                      reject(res);
                    },
                  }),
                  getParameterVauleByCode({
                    data: { code: "queryCreateInfo" },
                    success: (res) => {
                      let value =
                        !res.objx || !res.objx.value ? "0" : res.objx.value;
                      commit("SET_QUERY_CREATE_INFO", value);
                    },
                    fail: (res) => {
                      flag = false;
                      reject(res);
                    },
                  }),
                  getFileServerInfo({
                    failMsg: false,
                    errorMsg: false,
                    success: (res) => {
                      commit("SET_FILE_SERVER_INFO", res.objx);
                    },
                  }).catch((error) => {
                    console.error(error);
                  }),
                ];
                if (settingConfig.utcTransformEnabled) {
                  requests.push(
                    getParameterVauleByCode({
                      data: { code: "utcTransformOffset" }, //UTC时间转换时差
                      success: (res) => {
                        let value =
                          !res.objx || !res.objx.value
                            ? 0
                            : Number(res.objx.value);
                        if (isNaN(value)) value = 0;
                        commit("SET_UTC_TRANSFORM_OFFSET", value);
                      },
                      fail: (res) => {
                        flag = false;
                        reject(res);
                      },
                    })
                  );
                }
                if (settingConfig.i18nEnabled) {
                  requests.push(
                    languageSettingListPage({
                      success: (res) => {
                        let lang = window.$vueRoot.$i18n.locale;
                        let languageSettings = [
                          {
                            languageCode: "zh",
                            languageName: "中文",
                          },
                        ];
                        languageSettings.push(...(res.objx?.records || []));
                        if (lang != "zh") {
                          let currentItem = languageSettings.find(
                            (item) => item.languageCode == lang
                          );
                          if (isBdAdmin || !currentItem) {
                            lang = "zh";
                            window.$vueRoot.$i18n.locale = lang; // 设置给本地的i18n插件
                            localStorage.setItem("i18n-lang", lang);
                          }
                        }

                        commit("SET_LANGUAGE_SETTINGS", languageSettings);
                      },
                      fail: (res) => {
                        flag = false;
                        reject(res);
                      },
                    })
                  );
                }
                Promise.all(requests)
                  .then((responses) => {
                    if (flag) {
                      resolve(response);
                    }
                  })
                  .catch((error) => {
                    // 至少一个请求失败了
                    console.error(error);
                    reject(error);
                  });
              } else {
                reject(response);
              }
            }
          },
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

  // user logout
  logout2({ commit, state, dispatch }) {
    return new Promise((resolve, reject) => {
      configUtil.logout({
        success: (res) => {
          actions
            .resetToken({
              commit,
              state,
              dispatch,
            })
            .then(() => {
              resolve();
            });
        },
      });
    });
  },
  // remove token
  resetToken({ commit, state, dispatch }) {
    return new Promise((resolve) => {
      commit("SET_TOKEN", "");
      commit("SET_ROLES", []);
      commit("SET_NICK_NAME", "");
      commit("SET_LOGIN_ACCOUNT", "");
      commit("SET_COMPANY_CODE", "");
      commit("SET_USER_ID", "");
      configUtil.clearToken();
      configUtil.resetRouter();
      sessionStorage.removeItem("easyweb");

      dispatch("tagsView/delAllViews", null, {
        root: true,
      });
      resolve();
    });
  },

  // dynamically modify permissions
  async changeRoles({ commit, dispatch }, role) {
    const token = role + "-token";

    commit("SET_TOKEN", token);
    configUtil.setToken(token);

    const { roles } = await dispatch("getInfo");

    configUtil.resetRouter();

    // generate accessible routes map based on roles
    const accessRoutes = await dispatch("permission/generateRoutes", roles, {
      root: true,
    });
    // dynamically add accessible routes
    configUtil.router.addRoutes(accessRoutes);

    // reset visited views and cached views
    dispatch("tagsView/delAllViews", null, {
      root: true,
    });
  },
  changeCompanyInfo({ commit, dispatch }, row) {
    commit("SET_COMPANY_CODE", row.companyCode);
  },
  initLoginConfig({ commit, dispatch }, loginConfig) {
    return new Promise((resolve, reject) => {
      if (state.loginConfig === null) {
        getLoginConfig({
          failMsg: false,
          errorMsg: false,
          success: (res) => {
            let loginConfig = {};
            if (res.objx) {
              loginConfig = JSON.parse(res.objx);
              if (loginConfig.system_name)
                document.title = loginConfig.system_name;
            }
            commit("SET_LOGIN_CONFIG", loginConfig);
          },
        }).finally(() => {
          resolve();
        });
      } else {
        resolve();
      }
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
