// import CryptoJS from "crypto-js"
import { JSEncrypt } from "jsencrypt";
import service from "@/api/axios";

const encryptKey = "WfJTKO9S4eLkrPz2JKrAnzdb";
const encryptIV = "D076D35C";
/**
 * 登录密码加密，公钥直接写死在方法里
 * @param data： 待加密数据
 * @returns 加密结果
 */
export function encryptLoginPassword(data) {
  const secret =
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB";
  // 新建JSEncrypt对象
  let encryptor = new JSEncrypt();
  // 设置公钥
  encryptor.setPublicKey(secret);
  // 加密数据
  return encryptor.encrypt(data);
}

/**
 * 对称加密
 * @param secret：加密公钥
 * @param data： 待加密数据
 * @returns 加密结果
 */
export function encryptData(secret, data) {
  // 新建JSEncrypt对象
  let encryptor = new JSEncrypt();
  // 设置公钥
  encryptor.setPublicKey(secret);
  // 加密数据
  return encryptor.encrypt(data);
}

// 深度复制
export function deepClone(obj) {
  let result = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] === "object") {
        result[key] = deepClone(obj[key]);
      } else {
        result[key] = obj[key];
      }
    }
  }
  return result;
}

// // 3DES加密
// export function desEncrypt (str, key = encryptKey, iv = encryptIV) {
//   var cryptoKey = CryptoJS.enc.Utf8.parse(key)
//   var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
//   var encodeStr = CryptoJS.TripleDES.encrypt(str, cryptoKey, {
//     iv: cryptoIv,
//     mode: CryptoJS.mode.CBC,
//     padding: CryptoJS.pad.Pkcs7
//   })
//   return encodeStr.toString()
// }

// // 3DES解密
// export function desDecrypt (str, key = encryptKey, iv = encryptIV) {
//   var cryptoKey = CryptoJS.enc.Utf8.parse(key)
//   var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
//   var decryptStr = CryptoJS.TripleDES.decrypt(str, cryptoKey, {
//     iv: cryptoIv,
//     mode: CryptoJS.mode.CBC,
//     padding: CryptoJS.pad.Pkcs7
//   })
//   return decryptStr.toString(CryptoJS.enc.Utf8)
// }

// 随机生成由字母+数字的字符串
export function randomWord(randomFlag, min, max) {
  // randomFlag: Boolean 是否随机个数
  // min 最少个数
  // max 最大个数
  var str = "";
  var range = min;
  var arr = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "a",
    "b",
    "c",
    "d",
    "e",
    "f",
    "g",
    "h",
    "i",
    "j",
    "k",
    "l",
    "m",
    "n",
    "o",
    "p",
    "q",
    "r",
    "s",
    "t",
    "u",
    "v",
    "w",
    "x",
    "y",
    "z",
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
    "G",
    "H",
    "I",
    "J",
    "K",
    "L",
    "M",
    "N",
    "O",
    "P",
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W",
    "X",
    "Y",
    "Z",
  ];
  // 随机产生
  if (randomFlag) {
    range = Math.round(Math.random() * (max - min)) + min;
  }
  var pos = "";
  for (var i = 0; i < range; i++) {
    pos = Math.round(Math.random() * (arr.length - 1));
    str += arr[pos];
  }
  return str;
}

// 判断数组中是否存在相同值
export function hasRepeatValue(arr, key = null) {
  if (key) arr = arr.map((d) => d[key]);
  if (arr.length) {
    let nameNum = arr.reduce((pre, cur) => {
      if (cur in pre) {
        pre[cur]++;
      } else {
        pre[cur] = 1;
      }
      return pre;
    }, {});
    return Object.values(nameNum).findIndex((d) => d > 1) < 0;
  }
  return true;
}

// 获取cookie值
export function getCookie(name, defaultValue) {
  const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
  return result[0] === document.cookie.match(result[1])
    ? unescape(result[0][2])
    : defaultValue;
}

/**
 * base64转化unicode
 */
export function b64DecodeUnicode(str) {
  let uni;
  try {
    // atob 经过 base-64 编码的字符串进行解码
    uni = decodeURIComponent(
      atob(str)
        .split("")
        .map(function (c) {
          return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
        })
        .join("")
    );
  } catch (e) { }
  return uni;
}

// base64ToFile
export function base64ToFile(base64Data, tempfilename, contentType) {
  contentType = contentType || "";
  var sliceSize = 1024;
  var byteCharacters = atob(base64Data);
  var bytesLength = byteCharacters.length;
  var slicesCount = Math.ceil(bytesLength / sliceSize);
  var byteArrays = new Array(slicesCount);

  for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
    var begin = sliceIndex * sliceSize;
    var end = Math.min(begin + sliceSize, bytesLength);

    var bytes = new Array(end - begin);
    for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
      bytes[i] = byteCharacters[offset].charCodeAt(0);
    }
    byteArrays[sliceIndex] = new Uint8Array(bytes);
  }
  var file = new File(byteArrays, tempfilename, { type: contentType });
  return file;
}

// 将base64转换为文件
export function dataURLtoFile(dataurl, filename) {
  var arr = dataurl.split(",");
  var mime = arr[0].match(/:(.*?);/)[1];
  var bstr = atob(arr[1]);
  var n = bstr.length;
  var u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename, { type: mime });
}

// 将图片转换为Base64
export function getImgToBase64(url, callback, outputFormat) {
  var canvas = document.createElement("canvas");
  var ctx = canvas.getContext("2d");
  var img = new Image();
  img.crossOrigin = "Anonymous";
  img.onload = function () {
    canvas.height = img.height;
    canvas.width = img.width;
    ctx.drawImage(img, 0, 0);
    var dataURL = canvas.toDataURL(outputFormat || "image/png");
    callback(dataURL);
    canvas = null;
  };
  img.src = url;
}

// 转换级联下拉数据
export function loopOptions(list, option = {}) {
  option = {
    value: "id",
    label: "name",
    children: "children",
    ...option,
  };
  if (list instanceof Array && list.length) {
    return list.map((d, i) => {
      d.value = d[option.value] || i + 1;
      d.label = d[option.label];
      if (d[option.children]) {
        d[option.children] = loopOptions(d[option.children], option);
      }
      return d;
    });
  }
  return [];
}

// 通过Id获取级联数据id数组
export function getTreeIds(tree, currentId, key = "id") {
  let parent = {};
  let pid = {};
  const loop = (list, level) => {
    if (list instanceof Array && list.length) {
      for (let index = 0; index < list.length; index++) {
        const d = list[index];
        parent[level] = d.id;
        if (d[key] === currentId) {
          for (let idx = 1; idx <= level; idx++) {
            pid[idx] = parent[idx];
          }
          break;
        } else if (d.children) {
          loop(d.children, level + 1);
        }
      }
    }
  };
  loop(tree, 1);
  let result = [];
  Object.keys(pid)
    .sort((a, b) => a - b)
    .forEach((k) => {
      result.push(pid[k]);
    });
  return result;
}

/*
 * 格式化时间
 * yyyy-MM-dd hh:mm:ss
 * */
export function formatDate(date, fmt) {
  if (!date || date == null) return null;
  if (isNaN(date)) {
    return date;
  }
  let format = fmt || "yyyy-MM-dd hh:mm:ss";

  let dates = new Date(Number(date));

  let formatObj = {
    y: dates.getFullYear(),
    M: dates.getMonth() + 1,
    d: dates.getDate(),
    h: dates.getHours(),
    m: dates.getMinutes(),
    s: dates.getSeconds(),
  };
  let time_str = format.replace(/(y|M|d|h|m|s)+/g, (result, key) => {
    let value = formatObj[key];
    if (result.length > 0 && value < 10) {
      value = "0" + value;
    }
    return value || 0;
  });
  return time_str;
}

// 获取日期时间戳
export function getTime(dayNum) {
  var myDate = new Date();
  var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum); // 最后一个数字多少天前的意思
  var lastY = lw.getFullYear();
  var lastM = lw.getMonth() + 1;
  var lastD = lw.getDate();
  var startdate =
    lastY +
    "-" +
    (lastM < 10 ? "0" + lastM : lastM) +
    "-" +
    (lastD < 10 ? "0" + lastD : lastD);
  var b = startdate.split(/\D/);
  var date = new Date(b[0], b[1] - 1, b[2]);
  var time = date.getTime();
  return time;
}

// 获取几天之前日期
export function getData(dayNum) {
  var myDate = new Date();
  var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum); // 最后一个数字多少天前的意思
  var lastY = lw.getFullYear();
  var lastM = lw.getMonth() + 1;
  var lastD = lw.getDate();
  var startdate =
    lastY +
    "-" +
    (lastM < 10 ? "0" + lastM : lastM) +
    "-" +
    (lastD < 10 ? "0" + lastD : lastD);
  return startdate;
}

// 日期转换时间戳
export function getNewTime(dayNum) {
  var b = dayNum.split(/\D/);
  var date = new Date(b[0], b[1] - 1, b[2]);
  var time = date.getTime();
  return time;
}

/*
 * 获取URL参数
 *
 * */
export function getURLParams(variable) {
  let str = window.location.href.split("?")[1];
  if (!str) return null;
  let ar = str.split("&");
  let obj = {};
  let data;
  for (var i = 0; i < ar.length; i++) {
    var pair = ar[i].split("=");
    pair[1] = decodeURIComponent(pair[1]);

    if (pair[0] == variable) {
      data = pair[1];
      return pair[1];
    }
    if (pair[0]) {
      obj[pair[0]] = pair[1];
    }
  }
  return variable ? data : obj;
}

/**
 * 校验答案
 * @param {*} s 源字符串
 * @param {*} questionType 题型，2单选 3多选
 * @param {*} optionCount 选项数目
 * @param {*} questionCount 题目数目
 */
function filtterChar(s, b, optionCount) {
  const ms = "ABCDEFGHIJ";
  let rs = "";
  for (let i = 0; i < s.length; i++) {
    let c = s[i];
    if (c == "," || c == " " || c == "，") {
      if (!b) {
        continue;
      }
      c = ",";
    } else if (c < "A" || c >= ms[optionCount]) {
      continue;
    }
    rs += c;
  }
  return rs;
}

function removeDup(s) {
  const ms = "ABCDEFGHIJ";
  let rs = "";
  for (let i = 0; i < ms.length; i++) {
    if (s.indexOf(ms[i]) >= 0) {
      rs += ms[i];
    }
  }
  return rs;
}
export function checkAnswer(
  s,
  questionType,
  optionCount = 4,
  questionCount = 1
) {
  if (optionCount > 10 || questionCount < 1) {
    return null;
  }
  let pre = s;
  s = s.toUpperCase();
  s = filtterChar(s, questionType == 3 && questionCount > 1, optionCount);
  if (questionType == 2) {
    //单选
    if (s.length > questionCount) {
      s = s.substring(0, questionCount);
    }
  } else if (questionType == 3) {
    //多选
    //允许逗号
    let ss = s.split(",");
    let len = questionCount;
    if (len > ss.length) {
      len = ss.length;
    }
    let rs = "";
    for (let i = 0; i < len; i++) {
      rs += removeDup(ss[i]);
      if (i < len - 1) {
        rs += ",";
      }
    }
    s = rs;
  } else {
    return null;
  }
  return s;
}

export function downloadFile(fileName, files) {
  if (typeof window.navigator.msSaveBlob !== "undefined") {
    window.navigator.msSaveBlob(files, fileName);
  } else {
    let URL = window.URL || window.webkitURL;
    let objectUrl;
    if (files instanceof Blob) {
      objectUrl = URL.createObjectURL(files);
    } else {
      objectUrl = files;
    }
    const a = document.createElement("a");
    if (typeof a.download === "undefined") {
      window.location = objectUrl;
    } else {
      a.href = objectUrl;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      a.remove();
    }
  }
}
// 获取网络URL的blob，返回一个promise
export function getBlob(url) {
  return new Promise((resolve) => {
    resolve(
      service({
        url: url,
        withCredentials: true,
        method: "get",
        responseType: "blob",
      })
    );
  });
}
/**
 * 打包压缩下载
 */
export function compressAndDown(arr, fileName) {
  const zip = new JSZip();
  const promiseArr = [];
  arr.forEach((item) => {
    const promise = getBlob(item.reportPath).then((res) => {
      const fileName = item.testName;
      let sIdx = item.reportPath.lastIndexOf(".");
      const fileType = item.reportPath.substring(sIdx);
      zip.file(`${fileName}${fileType}`, res, { binary: true });
    });
    promiseArr.push(promise);
  });
  Promise.all(promiseArr).then(() => {
    zip
      .generateAsync({
        type: "blob",
        compression: "DEFLATE",
        compressionOptions: {
          level: 9,
        },
      })
      .then((res) => {
        FileSave.saveAs(res, fileName ? fileName : "报表.zip");
      });
  });
}

/**
 * 班级格式化为三级列表 学段-年级-班级
 * @param {*} data
 * @returns
 */
function setSectionName(num) {
  let txt = "";
  switch (num) {
    case 1:
      txt = "小学";
      break;
    case 2:
      txt = "中学";
      break;
    case 3:
      txt = "高中";
      break;
    case 4:
      txt = "大学";
      break;
  }
  return txt;
}
export function setGradeName(num) {
  let txt = "";
  switch (num) {
    case 1:
      txt = "一年级";
      break;
    case 2:
      txt = "二年级";
      break;
    case 3:
      txt = "三年级";
      break;
    case 4:
      txt = "四年级";
      break;
    case 5:
      txt = "五年级";
      break;
    case 6:
      txt = "六年级";
      break;
    case 7:
      txt = "初一";
      break;
    case 8:
      txt = "初二";
      break;
    case 9:
      txt = "初三";
      break;
    case 10:
      txt = "高一";
      break;
    case 11:
      txt = "高二";
      break;
    case 12:
      txt = "高三";
      break;
    case 13:
      txt = "大一";
      break;
    case 14:
      txt = "大二";
      break;
    case 15:
      txt = "大三";
      break;
    case 16:
      txt = "大四";
      break;
    case 51:
      txt = "一年级";
      break;
    case 52:
      txt = "二年级";
      break;
    case 53:
      txt = "三年级";
      break;
    case 54:
      txt = "四年级";
      break;
    case 55:
      txt = "五年级";
      break;
    case 56:
      txt = "六年级";
      break;
    case 57:
      txt = "七年级";
      break;
    case 58:
      txt = "八年级";
      break;
    case 59:
      txt = "九年级";
      break;
    default:
      txt = "其他";
      break;
  }
  return txt;
}
export function formatClass(data) {
  let sectionName = [];
  let sectionNameArr = [];
  data.map((item) => {
    if (!sectionName.includes(item.sectionName)) {
      sectionName.push(item.sectionName);
      sectionNameArr.push({
        value: item.sectionName,
        label: setSectionName(item.sectionName),
        children: [
          {
            value: item.gradeName,
            label: setGradeName(item.gradeName),
            children: [
              {
                value: item.classId,
                label: item.className,
              },
            ],
          },
        ],
      });
    } else {
      let hasGrade = false;
      let sectionIndex = 0;
      let gradeIndex = 0;
      sectionNameArr.map((items, index) => {
        items.map((grade, gradeInx) => {
          if (setGradeName(item.gradeName) == grade.value) {
            hasGrade = true;
            sectionIndex = index;
            gradeIndex = gradeInx;
          }
        });
      });
      if (hasGrade) {
        sectionNameArr[sectionIndex].children[gradeIndex].push({
          value: item.classId,
          label: item.className,
        });
      } else {
        sectionNameArr[sectionIndex].children.push({
          value: setGradeName(item.gradeName),
          label: setGradeName(item.gradeName),
          children: [
            {
              value: item.classId,
              label: item.className,
            },
          ],
        });
      }
    }
  });
  return sectionNameArr;
}
export function formatGradeClass(data) {
  let gradeName = [];
  let gradeNameArr = [];
  data.map((item) => {
    if (!gradeName.includes(item.gradeName)) {
      gradeName.push(item.gradeName);
      gradeNameArr.push({
        value: item.grade,
        label: item.gradeName,
        children: [
          {
            value: item.id,
            label: item.className,
          },
        ],
      });
    } else {
      let gradeIndex = 0;
      gradeNameArr.map((items, index) => {
        if (items.value == item.grade) {
          gradeIndex = index;
        }
      });
      gradeNameArr[gradeIndex].children.push({
        value: item.id,
        label: item.className,
      });
    }
  });
  return gradeNameArr;
}
export function formatGradeNameClass(data) {
  let gradeName = [];
  let gradeNameArr = [];
  data.map((item) => {
    if (!gradeName.includes(item.gradeName)) {
      gradeName.push(item.gradeName);
      gradeNameArr.push({
        value: item.gradeName,
        label: item.gradeName,
        grade: item.grade,
        children: [
          {
            value: item.id,
            label: item.className,
            leaf: true
          },
        ],
      });
    } else {
      let gradeIndex = 0;
      gradeNameArr.map((items, index) => {
        if (items.value == item.gradeName) {
          gradeIndex = index;
        }
      });
      gradeNameArr[gradeIndex].children.push({
        value: item.id,
        label: item.className,
        leaf: true
      });
    }
  });
  return gradeNameArr;
}

export function tablePrint(id, title, type = null) {
  let divs = document.getElementById(id);
  let awin = window.open("", "_blank");
  awin.document.getElementsByTagName(
    "head"
  )[0].innerHTML = `<style> @media print {@page {size:A4 landscape;margin:10mm}
    body{margin:5mm;font-size:8px;}}
    body{-webkit-print-color-adjust: exact;}
    .tit{text-align:center;font-size:20px;color:#333;line-height:24px;font-weight:700;padding:10px 0;margin:0;}
    .table-box,.el-table,.el-table__body-wrapper,.el-table--border{max-height:99999999px!important;height:auto;width:auto!important;max-width:1400px;margin: 0 auto;}
    .el-table{width:100%}
    .el-table,.el-table__body-wrapper{max-height:auto}
    .el-table .el-table__cell{padding:12px 0}
    .el-table thead tr:first-child th.el-table__cell{border-top: 1px solid #ccc}
    .el-table thead tr:first-child th.el-table__cell:first-child{border-left: 1px solid #ccc;}
    .el-table thead tr th.el-table__cell{background:#ccc}
    .el-table tbody tr td.el-table__cell:first-child{border-left: 1px solid #ccc;}
    .el-table td.el-table__cell{border-bottom: 1px solid #ccc;}
    .el-table--border .el-table__cell{border-right: 1px solid #ccc;}
    .el-table--border th.el-table__cell, .el-table__fixed-right-patch{border-bottom: 1px solid #ccc;}
    .el-table .el-table__cell.gutter{border:none!important;}
    .el-table__fixed{display:none!important}
    .el-table .el-table__cell.is-center{text-align:center!important}
    .el-table .el-table__cell.is-hidden>*{visibility: inherit;}
    .el-table__cell.gutter{display:none}
    ul,li{margin:0;padding:0;list-style:none}
    .hui-box{display: flex;text-align: center;}
    .hui-box .s-txt{width: 61px;line-height: 144px;background: #ccc;font-size: 16px;color: #fff;font-weight: 700;border:1px solid #ccc;box-sizing:border-box}
    .hui-li{display: flex;}
    .hui-s{height: 48px;line-height: 48px;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;box-sizing: border-box;}
    .hui-s.s1{width: 100px;}
    .hui-s.s2{ width: 110px;}
    .hui-s.s3{width: 120px;}
    .info { display: flex;flex-wrap: wrap;border-left: 1px solid #ccc;border-top: 1px solid #ccc;margin-bottom: 12px;}
    .info-item {width: 25%;height: 50px;box-sizing: border-box;flex-shrink: 0;background: #f8f8f8;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;line-height: 50px;text-align: center;}
    .el-table__header,.el-table__body{width:100%!important;}
    #print-table{max-width:1400px;margin: 0 auto;width: 100%;}
    .hide{max-width:1400px;margin: 0 auto;width: 100%;border-left: 1px solid #ccc;border-spacing:0;box-sizing:border-box}
    .hide thead th{background:#ccc;line-height: 48px;border-right: 1px solid #ccc;box-sizing:border-box}
    .hide tbody tr td{line-height: 48px;border-right: 1px solid #ccc;text-align:center;box-sizing:border-box}
    .hide td{border-bottom: 1px solid #ccc;}
    </style>`;
  let aDom = divs.cloneNode(true);
  if (!type) {
    let aTbody = aDom.getElementsByClassName("el-table__body")[0]?.getElementsByTagName("tbody")[0];
    aDom.getElementsByClassName("el-table__header")[0].append(aTbody);
  }
  if (title) {
    let pTit = awin.document.createElement('p')
    pTit.className = "tit"
    pTit.innerHTML = title
    awin.document.body.append(pTit)
  }
  awin.document.body.append(aDom);
  awin.print();
  awin.close()
}