import { ref } from "vue";
import { isURL, validatenull } from "@/utils/validate";
import { ILogin } from "@/const/interface_type";
import { loginByUsername, refreshToken, getUserInfo, logout } from "@/api/login";
import { getMenu } from "@/api/admin";
import { encryption, deepClone } from "@/utils/util";

import cache from "@/utils/cache";
import webiste from "@/const/website";

function addPath(ele: any, first?: any) {
  const menu = webiste.menu as any;
  const propsConfig = menu.props;
  const propsDefault = {
    label: propsConfig.label || "name",
    path: propsConfig.path || "path",
    icon: propsConfig.icon || "icon",
    children: propsConfig.children || "children"
  };
  const icon = ele[propsDefault.icon];
  ele[propsDefault.icon] = validatenull(icon) ? menu.iconDefault : icon;
  const isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0;
  if (!isChild) ele[propsDefault.children] = [];
  if (!isChild && first && !isURL(ele[propsDefault.path])) {
    ele[propsDefault.path] = ele[propsDefault.path] + "/index";
  } else {
    ele[propsDefault.children].forEach((child: any) => {
      addPath(child);
    });
  }
}

export default {
  state: (): {
    access_token: string;
    refresh_token: string;
    userInfo: any;
    permissions: any;
    menu: any;
    roles: string[];
  } => ({
    access_token: cache.session.get("access_token") || "",
    refresh_token: cache.session.get("refresh_token") || "",
    userInfo: cache.session.getJSON("userInfo") || {},
    permissions: cache.session.getJSON("permissions") || {},
    menu: cache.session.getJSON("menu") || [],
    roles: []
  }),
  mutations: {
    SET_ACCESS_TOKEN: (state: any, access_token: string) => {
      state.access_token = access_token;
      cache.session.set("access_token", state.access_token);
    },
    REMOVE_ACCESS_TOKEN: (state: any) => {
      state.access_token = "";
      cache.session.remove("access_token");
    },
    SET_REFRESH_TOKEN: (state: any, rfToken: string) => {
      state.refresh_token = rfToken;
      cache.session.set("refresh_token", state.refresh_token);
    },
    REMOVE_REFRESH_TOKEN: (state: any) => {
      state.refresh_token = "";
      cache.session.remove("refresh_token");
    },
    SET_USER_INFO: (state: any, userInfo: any) => {
      state.userInfo = userInfo;
      cache.session.setJSON("userInfo", state.userInfo);
    },
    REMOVE_USER_INFO: (state: any) => {
      state.userInfo = {};
      cache.session.remove("userInfo");
    },
    SET_ROLES: (state: any, roles: string[]) => {
      state.roles = roles;
    },
    REMOVE_ROLES: (state: any) => {
      state.roles = [];
    },
    SET_PERMISSIONS: (state: any, permissions: string[]) => {
      const list = <any>{};
      for (let i = 0; i < permissions.length; i++) {
        list[permissions[i]] = true;
      }
      state.permissions = list;
      cache.session.setJSON("permissions", state.permissions);
    },
    REMOVE_PERMISSIONS: (state: any) => {
      state.permissions = [];
      cache.session.remove("permissions");
    },
    SET_MENU: (state: any, params: any = {}) => {
      const { menu, type } = params;
      if (type !== false) state.menu = menu;
      cache.session.setJSON("menu", state.menu);
    },
    REMOVE_MENU: (state: any) => {
      state.menu = [];
      cache.session.remove("menu");
    }
  },
  actions: {
    // 根据用户名登录
    LoginByUsername({ commit }: any, userInfo: ILogin) {
      const user = ref<ILogin>();
      if (webiste.passwordEnc) {
        user.value = encryption({
          data: userInfo,
          key: "pigxpigxpigxpigx",
          param: ["password"]
        });
      } else {
        user.value = userInfo;
      }
      return new Promise((resolve, reject) => {
        if (!user.value) return;
        loginByUsername(user.value)
          .then((response: any) => {
            commit("SET_ACCESS_TOKEN", response.access_token);
            commit("SET_REFRESH_TOKEN", response.refresh_token);
            // commit("CLEAR_LOCK");
            resolve(response);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
    // 刷新token
    RefreshToken({ commit, state }: any) {
      return new Promise((resolve, reject) => {
        refreshToken(state.refresh_token)
          .then((response) => {
            const data = response.data;
            commit("SET_ACCESS_TOKEN", data.access_token);
            commit("SET_REFRESH_TOKEN", data.refresh_token);
            // commit("CLEAR_LOCK");
            resolve(response);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
    // 查询用户信息
    GetUserInfo({ commit }: any) {
      return new Promise((resolve, reject) => {
        getUserInfo()
          .then((res) => {
            const data = res.data || {};
            const userInfo = data.sysUser;
            userInfo.deptName = data.deptName;
            userInfo.deptType = data.deptType;
            commit("SET_USER_INFO", userInfo);
            commit("SET_ROLES", data.roles || []);
            commit("SET_PERMISSIONS", data.permissions || []);
            resolve(data.sysUser);
          })
          .catch(() => {
            reject();
          });
      });
    },
    // 登出
    LogOut({ commit }: any) {
      return new Promise((resolve, reject) => {
        logout()
          .then(() => {
            commit("REMOVE_MENU", []);
            commit("REMOVE_PERMISSIONS", []);
            commit("REMOVE_USER_INFO", {});
            commit("REMOVE_ACCESS_TOKEN", "");
            commit("REMOVE_REFRESH_TOKEN", "");
            commit("REMOVE_ROLES", []);
            cache.session.removeAll();
            cache.local.removeAll();
            // commit("DEL_ALL_TAG");
            // commit("CLEAR_LOCK");
            // commit("DEL_DICTORY");
            location.reload();
            resolve("");
          })
          .catch((error: any) => {
            reject(error);
          });
      });
    },
    // 获取系统菜单
    GetMenu({ commit }: any, obj: any) {
      // 记录用户点击顶部信息，保证刷新的时候不丢失
      // commit("LIKE_TOP_MENUID", obj);
      return new Promise((resolve) => {
        getMenu(obj.id).then((res) => {
          const data = res.data;
          const menu = deepClone(data);
          menu.forEach((ele: any) => {
            addPath(ele);
          });
          const type = obj.type;
          commit("SET_MENU", { type, menu });
          resolve(menu);
        });
      });
    }
  }
};
