import router from "@/router";
import { store } from "@/store/store";
import CryptoJS from "crypto-js";
import { MD5 } from "./md5";

export function setUUID() {
  if (!localStorage.getItem("uuidForEcs")) {
    const uuidForEcs = "" + Date.now() + Math.random();
    localStorage.setItem("uuidForEcs", uuidForEcs);
  }
}

// 如果这台机器上登录过的学生人数小于5，那么这台电脑就是学生的
export function isThisMachineOwnByStudent() {
  return JSON.parse(localStorage.getItem("userIds") || "[]").length < 5;
}

/** 通用的退出登录函数
 * @param cause - 退出登录的原因
 */
export function showLogout(cause: string) {
  logger({
    pgu: "AUTO",
    cnl: ["console", "local", "server"],
    dtl: "用户被要求重新登录",
    ext: { cause },
  });
  $message.warning(cause, { duration: 5 * 60 * 1000, closable: true });
  void router.push({ name: "UserLogin" });
}

/**
 * 将阿拉伯数字转换成汉字数字
 * @param num 数值
 * @returns 汉字数字
 */
export function toChineseNumber(num: number) {
  let ret = "";
  if (num < 10) {
    ret = num.toLocaleString("zh-u-nu-hanidec");
  } else if (num === 10) {
    ret = "十";
  } else if (num > 10 && num < 20) {
    ret = "十" + (num % 10).toLocaleString("zh-u-nu-hanidec");
  } else if (num >= 20 && num < 100) {
    const s = num
      .toLocaleString("zh-u-nu-hanidec", { useGrouping: false })
      .split("");
    s.splice(1, 0, "十");
    ret = s.join("").replace("〇", "");
  } else {
    ret = num.toLocaleString("zh-u-nu-hanidec"); // 假设没有超过100的大题
  }

  return ret;
}

export function preloadResource(url: string) {
  const preloadLink = document.createElement("link");
  preloadLink.href = url;
  preloadLink.rel = "preload";
  preloadLink.as = "script";
  document.head.appendChild(preloadLink);
}

// let salt: string;
// export function setSalt(_salt: string) {
//   salt = _salt;
// }

export function getSalt() {
  return store.user.salt;
}

export function getKey(timestamp: number) {
  const { key, token } = store.user;
  if (!key || !token) return "";

  return MD5(`key=${key}&token=${token}&timestamp=${timestamp}`);
}

function toHex(str: string) {
  if (!str) {
    return "";
  }

  const chars = [];
  for (let n = 0; n < str.length; n++) {
    chars.push(str.charCodeAt(n).toString(16));
  }
  return chars.join("");
}

const ivStr = "@M#A$G%A^2&0*2(1"; // 偏移量
const iv = toHex(ivStr); // 16进制偏移量
export function decryptLogin(encStr: string, key: string): string {
  return CryptoJS.enc.Utf8.stringify(
    CryptoJS.AES.decrypt(
      CryptoJS.format.Hex.parse(encStr),
      CryptoJS.enc.Hex.parse(toHex(key)),
      {
        iv: CryptoJS.enc.Hex.parse(iv),
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
      }
    )
  );
}

/** AES(带向量) 简写 A */
export function encryptA(str: string, key: string) {
  return CryptoJS.AES.encrypt(str, CryptoJS.enc.Hex.parse(toHex(key)), {
    // iv: CryptoJS.enc.Hex.parse(iv),
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  }).ciphertext.toString();
}

export function decryptA(encStr: string, key: string): string {
  return CryptoJS.enc.Utf8.stringify(
    CryptoJS.AES.decrypt(
      CryptoJS.format.Hex.parse(encStr),
      CryptoJS.enc.Hex.parse(toHex(key)),
      {
        // iv: CryptoJS.enc.Hex.parse(iv),
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7,
      }
    )
  );
}

/** base64加密 简写B */
export function encryptB(str: string): string {
  // return window.btoa(str);
  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str));
}

/** base64加密 简写B */
export function decryptB(str: string): string {
  return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(str));
}

/** RC4(无向量) 简写 C */
export function encryptC(str: string, key: string) {
  return CryptoJS.RC4.encrypt(
    str,
    CryptoJS.enc.Hex.parse(toHex(key))
  ).toString();
}

export function decryptC(encStr: string, key: string): string {
  return CryptoJS.enc.Utf8.stringify(
    CryptoJS.RC4.decrypt(encStr, CryptoJS.enc.Hex.parse(toHex(key)))
  );
}

/** DES(无向量) 简写 D */
export function encryptD(str: string, key: string) {
  return CryptoJS.DES.encrypt(str, CryptoJS.enc.Hex.parse(toHex(key)), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  }).toString();
}

export function decryptD(encStr: string, key: string): string {
  return CryptoJS.enc.Utf8.stringify(
    CryptoJS.DES.decrypt(encStr, CryptoJS.enc.Hex.parse(toHex(key)), {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    })
  );
}

/** TripleDES(无向量) 简写 E */
export function encryptE(str: string, key: string) {
  return CryptoJS.TripleDES.encrypt(str, CryptoJS.enc.Hex.parse(toHex(key)), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  }).toString();
}

export function decryptE(encStr: string, key: string): string {
  return CryptoJS.enc.Utf8.stringify(
    CryptoJS.TripleDES.decrypt(encStr, CryptoJS.enc.Hex.parse(toHex(key)), {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    })
  );
}
