import CryptoJS from 'crypto-js'
export var APPSTR_DES_CBC_KEY = 'AIOPS_CBC_KEY'
// DES加密
export var encryptByDES = {
  ECB: function (message, key, keepLetterCase = false) {
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    })
    if (keepLetterCase) {
      return encrypted.ciphertext.toString()
    }
    return encrypted.ciphertext.toString().toLowerCase()
  },
  CBC: function (message, key, keepLetterCase = false) {
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
      iv: keyHex,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    })
    if (keepLetterCase) {
      return encrypted.ciphertext.toString()
    }
    return encrypted.ciphertext.toString().toLowerCase()
  },
}

export var decryptByDES = {
  ECB: function (ciphertext, key) {
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    var decrypted = CryptoJS.DES.decrypt(
      {
        ciphertext: CryptoJS.enc.Hex.parse(ciphertext.toLowerCase()),
      },
      keyHex,
      {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7,
      },
    )
    return decrypted.toString(CryptoJS.enc.Utf8)
  },
  CBC: function (ciphertext, key) {
    var keyHex = CryptoJS.enc.Utf8.parse(key)
    var decrypted = CryptoJS.DES.decrypt(
      {
        ciphertext: CryptoJS.enc.Hex.parse(ciphertext.toLowerCase()),
      },
      keyHex,
      {
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
        iv: keyHex,
      },
    )
    return decrypted.toString(CryptoJS.enc.Utf8)
  },
}

// CryptoJS加密
export function encryptByBase64(message) {
  var str = CryptoJS.enc.Utf8.parse(message)
  return CryptoJS.enc.Base64.stringify(str)
}
export function decryptByBase64(encryptedStr) {
  var words = CryptoJS.enc.Base64.parse(encryptedStr)
  return words.toString(CryptoJS.enc.Utf8)
}
export function encryptByMD5(message) {
  var words = CryptoJS.MD5(message)
  return words.toString()
}
/**
 * 日期格式化
 * 例：dateFormat(new Date(), "YYYY/MM/DD hh:mm:ss S")
 * 支持格式YYYY,yyyy MM DD,dd HH,hh mm ss, S(毫秒)
 */
export function dateFormat(date, fmt) {
  // console.log(date, fmt)
  if (!date) {
    return ''
  }
  if (!(date instanceof Date)) {
    if (typeof date === 'number') {
      date = '' + date
    }
    date = date.trim()
    var fixstr = '1970/01/01' // 用于修复只传了年或只传了年月在IOS设备上new Date()不兼容的问题
    var datePre = date.substr(0, 10).replace(/[.]|-|\\|,/gi, '/')
    datePre = datePre + fixstr.substr(datePre.length)
    var datePost = date.substr(10)
    date = datePre + datePost
    // TxtToast('' + date)
    date = new Date(date)
  }
  if (isNaN(date.getTime())) {
    return ''
  }
  var o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  }
  if (/(y+)/i.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  for (var k in o) {
    if ((['d+', 'h+'].indexOf(k) === -1 ? new RegExp('(' + k + ')') : new RegExp('(' + k + ')', 'i')).test(fmt))
      fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
  }
  return fmt
}

/**
 * 提示
 * frameDiv 需要添加提示的div元素
 */
export function createTooltip(frameDiv, direction = 'right') {
  var tooltip = function (frameDiv) {
    var div = document.createElement('DIV')
    div.className = `twipsy ${direction}`

    var arrow = document.createElement('DIV')
    arrow.className = 'twipsy-arrow'
    div.appendChild(arrow)

    var title = document.createElement('DIV')
    title.className = 'twipsy-inner'
    div.appendChild(title)

    this._div = div
    this._title = title
    this.message = ''

    // add to frame div and display coordinates
    frameDiv.appendChild(div)
    var that = this
    div.onmousemove = function (evt) {
      that.showAt({ x: evt.clientX, y: evt.clientY }, that.message)
    }
  }

  tooltip.prototype.setVisible = function (visible) {
    this._div.style.display = visible ? 'block' : 'none'
  }

  tooltip.prototype.showAt = function (position, message) {
    if (position && message) {
      this.setVisible(true)
      this._title.innerHTML = message
      if (direction === 'top') {
        this._div.style.left = position.x - this._div.clientWidth / 2 + 'px'
        this._div.style.top = position.y - this._div.clientHeight - 15 + 'px'
      }
      if (direction === 'right') {
        this._div.style.left = position.x + 10 + 'px'
        this._div.style.top = position.y - this._div.clientHeight / 2 + 'px'
      }
      this.message = message
    }
  }

  tooltip.prototype.destroy = function () {
    try {
      div && frameDiv.removeChild(div)
    } catch (error) {
      console.log(error)
    }
  }

  return new tooltip(frameDiv)
}
/**
 * element plus自动回弹
 * event 点击事件的返回的event对象
 */
export function unFoucs(event) {
  // event.target.blur()
  // if (event.target.nodeName === 'SPAN') {
  //   event.target.parentNode.blur()
  // }
  event.target.blur()
  if (event.target.nodeName === 'SPAN') {
    if (event.target.children.length == 0) {
      event.target.parentNode.parentNode.blur()
    }
    event.target.parentNode.blur()
  }
  if (event.target.nodeName === 'IMG') {
    const evt = event.target.parentNode.parentNode
    evt.blur()
  }
}
/**
 * element plus自定义删除弹窗
 * msg: 删除提示语，回调函数使用.then
 */
import { h } from 'vue'
import { ElMessageBox } from 'element-plus'
export function deletebox(msg1, title = '提示') {
  return new Promise((resolve, reject) => {
    ElMessageBox.confirm(
      h('div', { class: 'df fdc jcsb aic' }, [
        // h('img', { src: './img/common/icon_del.png' }),
        //class: 'mt20',
        h(
          'div',
          { style: 'word-wrap: break-word;word-break: break-all; line-height: 20px;' },
          msg1 || '您是否确定删除',
        ),
        // h('div', { class: 'mt20' }, msg2 || ''),
      ]),
      title,
      {
        type: 'warning',
        // icon: h('img', { src: './img/common/icon_tips.png' }),
        autofocus: false,
        customClass: 'message-box',
        // distinguishCancelAndClose: true,
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        dangerouslyUseHTMLString: true,
        // buttonSize: 'large',
        // type: 'info',
        center: true,
      },
    )
      .then(() => {
        resolve()
      })
      .catch(action => {
        // reject(action)
      })
  })
}

/**
 * 深拷贝
 * data: 要拷贝的对象
 */
export function deepCopy(data, hash = new WeakMap()) {
  if (typeof data !== 'object' || data === null) {
    throw new TypeError('传入参数不是对象')
  }
  // 判断传入的待拷贝对象的引用是否存在于hash中
  if (hash.has(data)) {
    return hash.get(data)
  }
  let newData = {}
  const dataKeys = Object.keys(data)
  dataKeys.forEach(value => {
    const currentDataValue = data[value]
    // 基本数据类型的值和函数直接赋值拷贝
    if (typeof currentDataValue !== 'object' || currentDataValue === null) {
      newData[value] = currentDataValue
    } else if (Array.isArray(currentDataValue)) {
      // 实现数组的深拷贝
      newData[value] = [...currentDataValue]
    } else if (currentDataValue instanceof Set) {
      // 实现set数据的深拷贝
      newData[value] = new Set([...currentDataValue])
    } else if (currentDataValue instanceof Map) {
      // 实现map数据的深拷贝
      newData[value] = new Map([...currentDataValue])
    } else {
      // 将这个待拷贝对象的引用存于hash中
      hash.set(data, data)
      // 普通对象则递归赋值
      newData[value] = deepCopy(currentDataValue, hash)
    }
  })
  return newData
}

/**
 * element plus自定义页面返回弹框
 * msg: 返回提示语，回调函数使用.then
 */
export function canclebox(msg1, msg2) {
  return new Promise((resolve, reject) => {
    ElMessageBox.confirm(
      h('div', { class: 'df fdc jcsb aic' }, [
        h('div', { class: 'mt20' }, msg1 || '您是否确定返回'),
        h('div', msg2 || ''),
      ]),
      '提示',
      {
        icon: h('img', { src: './img/common/icon_tips.png' }),
        autofocus: false,
        customClass: 'message-box',
        // distinguishCancelAndClose: true,
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        dangerouslyUseHTMLString: true,
        buttonSize: 'large',
        // type: 'info',
        center: true,
      },
    )
      .then(() => {
        resolve()
      })
      .catch(action => {
        reject(action)
      })
  })
}

import { ElMessage } from 'element-plus'
export function message(message, type) {
  ElMessage[type]({
    message,
    offset: window.screen.height / 2 - 100,
  })
}

//加法：

export function dcmAdd(arg1, arg2) {
  var r1, r2, m
  try {
    r1 = arg1.toString().split('.')[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split('.')[1].length
  } catch (e) {
    r2 = 0
  }
  m = Math.pow(10, Math.max(r1, r2))
  return (accMul(arg1, m) + accMul(arg2, m)) / m
}
//减法：

export function dcmReduce(arg1, arg2) {
  var r1, r2, m
  try {
    r1 = arg1.toString().split('.')[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split('.')[1].length
  } catch (e) {
    r2 = 0
  }
  m = Math.pow(10, Math.max(r1, r2))
  return (accMul(arg1, m) - accMul(arg2, m)) / m
}
//乘法：

export function accMul(arg1, arg2) {
  var m = 0,
    s1 = arg1.toString(),
    s2 = arg2.toString()
  try {
    m += s1.split('.')[1].length
  } catch (e) { }
  try {
    m += s2.split('.')[1].length
  } catch (e) { }
  return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m)
}
//除法：

export function accDiv(arg1, arg2) {
  var t1 = 0,
    t2 = 0,
    r1,
    r2
  try {
    t1 = arg1.toString().split('.')[1].length
  } catch (e) { }
  try {
    t2 = arg2.toString().split('.')[1].length
  } catch (e) { }
  Math.r1 = Number(arg1.toString().replace('.', ''))
  Math.r2 = Number(arg2.toString().replace('.', ''))
  return (Math.r1 / Math.r2) * Math.pow(10, t2 - t1)
}

/**
 * @description: 判断两个对象是否相等
 * @param {*} obj1 时间对象和函数对象不做比对
 * @param {*} obj2
 * @return {*}
 */
export function isEqual(obj1, obj2) {
  if (!isObject(obj1) && !isObject(obj2)) {
    // 两个都是基本类型，直接进行严格比较
    if (Number.isNaN(obj1) && Number.isNaN(obj2)) {
      return true
    }
    return obj1 === obj2
  }
  if (!isObject(obj1) || !isObject(obj2)) {
    // 一个对象，一个基本类型，直接返回 false
    return false
  }
  if (typeOf(obj1) !== typeOf(obj2)) {
    // 类型不同，直接返回 false
    return false
  }
  // 后面比较的都是类型相同的对象类型
  if (obj1 === obj2) {
    // 直接比较引用地址，相等则返回 true
    return true
  }
  if (['Array', 'Object'].includes(typeOf(obj1))) {
    //  plain object 和 array，for ... in 比较每一项值
    let l1 = Object.keys(obj1).length
    let l2 = Object.keys(obj2).length
    if (l1 !== l2) {
      return false
    }
    for (let k in obj1) {
      if (!isEqual(obj1[k], obj2[k])) {
        return false
      }
    }
    return true
  }
  if (['Map', 'Set'].includes(typeOf(obj1))) {
    // 处理 map、set 类型，转换为数组再比较
    const [arr1, arr2] = [[...obj1], [...obj2]]
    return isEqual(arr1, arr2)
  }
  return false
}

function isObject(item) {
  return Object(item) === item
}

function typeOf(item) {
  return Object.prototype.toString.call(item).slice(8, -1)
}

export function debounce(fn, wait) {
  var timeout = null
  return function () {
    if (timeout !== null) clearTimeout(timeout)
    timeout = setTimeout(fn, wait)
  }
}
// 获取索引
export function findIndex(data, value, key) {
  // 传入key，则表示为对象，用键名查找
  console.log();
  return data.findIndex(ele => { return key ? value == ele[key] : value == ele })
}

// 表头顺序调整
export function sortTableHeader(indexNow, indexRes, path, headerList) {
  // 两两交换位置
  let data = headerList[indexRes]
  headerList[indexRes] = headerList[indexNow]
  headerList[indexNow] = data
  // 缓存表头排序
  let name =
    sessionStorage.getItem('userInfo') !== 'undefined' && sessionStorage.getItem('userInfo')
      ? JSON.parse($utils.decryptByDES.CBC(sessionStorage.getItem('userInfo'))).userName
      : ''
  window.localStorage.setItem(
    name + path + '_sort',
    JSON.stringify(headerList),
  )
}