/* eslint-disable */
// cnpm install -S file-saver xlsx xlsx-style
let idTmr
const getExplorer = () => {
  let explorer = window.navigator.userAgent
  //ie
  if (explorer.indexOf('MSIE') >= 0) {
    return 'ie'
  }
  //firefox
  else if (explorer.indexOf('Firefox') >= 0) {
    return 'Firefox'
  }
  //Chrome
  else if (explorer.indexOf('Chrome') >= 0) {
    return 'Chrome'
  }
  //Opera
  else if (explorer.indexOf('Opera') >= 0) {
    return 'Opera'
  }
  //Safari
  else if (explorer.indexOf('Safari') >= 0) {
    return 'Safari'
  }
}
// 判断浏览器是否为IE
const exportToExcel = (data, name) => {
  // 判断是否为IE
  if (getExplorer() == 'ie') {
    tableToIE(data, name)
  } else {
    tableToNotIE(data, name)
  }
}

const Cleanup = () => {
  window.clearInterval(idTmr)
}

// ie浏览器下执行
const tableToIE = (data, name) => {
  let curTbl = data
  let oXL = new ActiveXObject('Excel.Application')

  //创建AX对象excel
  let oWB = oXL.Workbooks.Add()
  //获取workbook对象
  let xlsheet = oWB.Worksheets(1)
  //激活当前sheet
  let sel = document.body.createTextRange()
  sel.moveToElementText(curTbl)
  //把表格中的内容移到TextRange中
  sel.select
  //全选TextRange中内容
  sel.execCommand('Copy')
  //复制TextRange中内容
  xlsheet.Paste()
  //粘贴到活动的EXCEL中

  oXL.Visible = true
  //设置excel可见属性

  try {
    let fname = oXL.Application.GetSaveAsFilename(
      'Excel.xls',
      'Excel Spreadsheets (*.xls), *.xls'
    )
  } catch (e) {
    print('Nested catch caught ' + e)
  } finally {
    oWB.SaveAs(fname)

    oWB.Close((savechanges = false))
    oXL.Quit()
    oXL = null
    // 结束excel进程，退出完成
    window.setInterval('Cleanup();', 1)
    idTmr = window.setInterval('Cleanup();', 1)
  }
}

// 非ie浏览器下执行
const tableToNotIE = (function () {
  // 编码要用utf-8不然默认gbk会出现中文乱码
  let uri = 'data:application/vnd.ms-excel;base64,',
    template =
      '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><style>td,th {padding:10px}</style><body><table><caption>{table}</caption></table></body></html>',
    base64 = function (s) {
      return window.btoa(unescape(encodeURIComponent(s)))
    },
    format = (s, c) => {
      return s.replace(/{(\w+)}/g, (m, p) => {
        return c[p]
      })
    }
  return (table, name) => {
    let ctx = {
      worksheet: name,
      table
    }
    //创建下载
    let link = document.createElement('a')
    link.setAttribute('href', uri + base64(format(template, ctx)))

    link.setAttribute('download', name)

    // window.location.href = uri + base64(format(template, ctx))
    link.click()
  }
})()

const isImage = (url) => {
  const httpReg = /http/
  const imgReg = /\.(png|jpe?g|gif|bmp|svg)$/i
  return imgReg.test(url) || httpReg.test(url)
}

/**
 * @param {*} theadMap
 * @param {*} tableData
 * @param {*} theadProps
 * @param {*} dataname
 * @param {*} tfootData
 * @param {*} baseApi
 */
const exportExcel = (obj) => {
  const { theadMap, tableData, theadProps, dataName, tfootData, baseApi } = obj
  console.log("🚀 导出表格数据tableData:", tableData)
  // 将数据拆分成每个数组15条的二位数组
  let splitTableDatas = []
  splitTableData()
  function splitTableData () {
    for (let i = 0; i < tableData.length; i += 15) {
      splitTableDatas.push(tableData.slice(i, i + 15))
    }
  }
  let th_len = theadMap.length // 表头的长度
  let split_len = splitTableDatas.length
  let tb_len = tableData.length // 记录条数
  let rest_len = tb_len % 15

  // 添加表头信息
  let thead = '<thead>'
  for (let i = 0; i < th_len; i++) {
    thead += '<tr>'
    for (const key in theadMap[i]) {
      if (theadMap[i].hasOwnProperty.call(theadMap[i], key)) {
        thead += '<th style="background-color: #f5f7fa;border: 1px solid #EBEEF5;height: 40px;" colspan=' + (theadMap[i][key].c || 0) + ' rowspan=' + (theadMap[i][key].r || 0) + '>' + key + '</th>'
      }
    }
    thead += '</tr>'
  }

  thead += '</thead>'
  // 添加每一行数据
  let tbody = '<tbody>'
  for (let k = 0; k < split_len; k++) {
    // console.log(15*(k+1)-rest_len)
    for (let i = 15 * k; i < ((k + 1) === split_len ? 15 * (k + 1) - (rest_len ? 15 - rest_len : 0) : 15 * (k + 1)); i++) {
      tbody += '<tr>'
      let row = tableData[i] // 获取每一行数据

      for (const key in theadProps) {
        if (isImage(row[key]) && theadProps[key].image) {
          // 如果为图片，则需要加div包住图片
          const formatImagesArr = formatImages(row[key], baseApi)
          tbody += '<td style="text-align:center;vertical-align:middle;" height="100" width="100">'
          for (let j = 0; j < formatImagesArr.length; j++) {
            tbody += `
              <img src='${formatImagesArr[j]}'" width="80" height="80"/>
              `
          }
          tbody += '</td>'
        } else if (theadProps[key].method) {
          tbody += '<td height="100" width="100" style="text-align:center;border: 1px solid #EBEEF5;">'
            // 前面加空格防止数据被excel自动格式化
            + ('&nbsp;' + (theadProps[key].method(row))) +
            '</td>'
        } else {
          tbody += '<td height="100" width="100" style="text-align:center;border: 1px solid #EBEEF5;">'
            // 前面加空格防止数据被excel自动格式化
            + ('&nbsp;' + (formatValue(row, theadProps, key))) +
            '</td>'
        }
      }
      tbody += '</tr>'
    }
  }
  tbody += '</tbody>'
  // 添加页脚
  let tfoot = '<tfoot>'
  for (let i = 0; i < tfootData.length; i++) {
    tfoot += '<tr>'
    for (let j = 0; j < tfootData[i].length; j++) {
      const arr = tfootData[i][j]
      tfoot += '<th style="background-color: #f5f7fa;border: 1px solid #EBEEF5;height: 40px;" colspan=' + (arr.c || 0) + ' rowspan=' + (arr.r || 0) + '>' + arr.value + '</th>'
    }
    tfoot += '</tr>'
  }
  tfoot += '</tfoot>'

  let table = thead + tbody + tfoot
  console.log("🚀 导出表格完整结构：", table)
  // 导出表格
  exportToExcel(table, dataName)
}
const formatImages = (images, api) => {
  const httpReg = /http/
  if (Array.isArray(images)) {
    for (let i = 0; i < images.length; i++) {
      images[i] = httpReg.test(images[i]) ? images[i] : api + images[i]
    }
    return images
  } if (isArrayFormat(images)) {
    let imagesArr = []
    try {
      imagesArr = JSON.parse(images)
    } catch (error) {
      imagesArr = [images]
      console.warn('图片json格式错误，请检查')
    }
    return formatImages(imagesArr, api)
  } else {
    const imagesArr = images.split(',')
    return formatImages(imagesArr, api)
  }
}
const isArrayFormat = (str) => {
  let stack = [];
  for (let i = 0; i < str.length; i++) {
    if (str[i] === '[') {
      stack.push(i);
    } else if (str[i] === ']') {
      if (stack.length === 0) {
        return false;
      }
      let startIndex = stack.pop();
      if (startIndex === 0) {
        return false;
      }
      let midIndex = str.indexOf(',', startIndex + 1);
      if (midIndex === -1) {
        return false;
      }
      let endIndex = str.indexOf(']', startIndex + 1);
      if (endIndex <= midIndex) {
        return false;
      }
    }
  }
  return stack.length === 0;
}
/**
 * 处理显示的值
 * @param {行数据} obj
 * @param {数据对应配置} theadProps
 * @param {属性值} key
 * @returns
 */
const formatValue = (obj, theadProps, key) => {
  const value = obj[key]
  if (value === undefined || value === null) {
    return ''
  } else if (theadProps[key] && theadProps[key].options && Object.keys(theadProps[key].options).length > 0) {
    return returnOptionsLabel(theadProps[key], value)
  } else if (theadProps[key] && theadProps[key].unit) {
    return addUnit(value, theadProps[key].unit)
  } else if (theadProps[key].html) {
    return removeHtml(value)
  } else {
    return value
  }
}
const removeHtml = (str) => {
  return String(str).replace(/<[^>]+>/g, '')
}
/**
 * 选项筛选对应的值
 * @param {value,label的数组格式进行筛选} options
 * @param {筛选的值} value
 * @returns
 */
const returnOptionsLabel = (itemObj, value) => {
  const item = itemObj.options.find((item) => {
    if (item.value === value) {
      return itemObj.unit ? addUnit(item.label) : item.label
    }
  })
  return item ? item.label : value
}
const addUnit = (value, unit) => {
  return String(value).indexOf(unit) > -1 ? value : `${value}${unit}`
}
export default exportExcel
