/* eslint-disable */
import XLSX from 'xlsx'

let FileSaver = require('file-saver')

function auto_width(ws, data) {
  /*set worksheet max width per col*/
  const colWidth = data.map((row) =>
    row.map((val) => {
      /*if null/undefined*/
      if (val == null) {
        return { wch: 10 }
      } else if (val.toString().charCodeAt(0) > 255) {
      /*if chinese*/
        return { wch: val.toString().length * 2 }
      } else {
        return { wch: val.toString().length }
      }
    })
  )
  /*start in the first row*/
  let result = colWidth[0]
  for (let i = 1; i < colWidth.length; i++) {
    for (let j = 0; j < colWidth[i].length; j++) {
      if (result[j]['wch'] < colWidth[i][j]['wch']) {
        result[j]['wch'] = colWidth[i][j]['wch']
      }
    }
  }
  ws['!cols'] = result
}

function json_to_array(key, jsonData) {
  return jsonData.map((v) =>
    key.map((j) => {
      return v[j]
    })
  )
}

// fix data,return string
function fixdata(data) {
  let o = ''
  let l = 0
  const w = 10240
  for (; l < data.byteLength / w; ++l)
    o += String.fromCharCode.apply(
      null,
      new Uint8Array(data.slice(l * w, l * w + w))
    )
  o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
  return o
}

// get head from excel file,return array
function get_header_row(sheet) {
  const headers = []
  const range = XLSX.utils.decode_range(sheet['!ref'])
  let C
  const R = range.s.r /* start in the first row */
  for (C = range.s.c; C <= range.e.c; ++C) {
    /* walk every column in the range */
    var cell =
      sheet[
        XLSX.utils.encode_cell({ c: C, r: R })
      ] /* find the cell in the first row */
    var hdr = 'UNKNOWN ' + C // <-- replace with your desired default
    if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
    headers.push(hdr)
  }
  return headers
}

export const export_table_to_excel = (id, filename) => {
  const table = document.getElementById(id)
  const wb = XLSX.utils.table_to_book(table)
  XLSX.writeFile(wb, filename)

  /* the second way */
  // const table = document.getElementById(id);
  // const wb = XLSX.utils.book_new();
  // const ws = XLSX.utils.table_to_sheet(table);
  // XLSX.utils.book_append_sheet(wb, ws, filename);
  // XLSX.writeFile(wb, filename);
}

export const export_json_to_excel = ({
  data,
  key,
  title,
  filename,
  autoWidth,
}) => {
  const wb = XLSX.utils.book_new()
  data.unshift(title)
  const ws = XLSX.utils.json_to_sheet(data, { header: key, skipHeader: true })
  if (autoWidth) {
    const arr = json_to_array(key, data)
    auto_width(ws, arr)
  }
  XLSX.utils.book_append_sheet(wb, ws, filename)
  XLSX.writeFile(wb, filename + '.xlsx')
}

export const export_array_to_excel = ({
  key,
  data,
  title,
  filename,
  autoWidth,
}) => {
  const wb = XLSX.utils.book_new()
  const arr = json_to_array(key, data)
  arr.unshift(title)
  const ws = XLSX.utils.aoa_to_sheet(arr)
  if (autoWidth) {
    auto_width(ws, arr)
  }
  XLSX.utils.book_append_sheet(wb, ws, filename)
  XLSX.writeFile(wb, filename + '.xlsx')
}

export const read = (data, type) => {
  /* if type == 'base64' must fix data first */
  // const fixedData = fixdata(data)
  // const workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
  const workbook = XLSX.read(data, { type: type })
  const firstSheetName = workbook.SheetNames[0]
  const worksheet = workbook.Sheets[firstSheetName]
  const header = get_header_row(worksheet)
  const results = XLSX.utils.sheet_to_json(worksheet)
  return { header, results }
}

/**
 * 导出Excel文件
 * @param wb
 */
export function exportToExcel(excelName, list, ws_name) {
  const wb = { SheetNames: [], Sheets: {}, Props: {} }
  wb.SheetNames.push(ws_name)
  wb.Sheets[ws_name] = XLSX.utils.json_to_sheet(list)
  //wb.Sheets['借出申请1'] = XLSX.utils.json_to_sheet(list);
  const wopts = {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary',
    defaultCellStyle: null,
    showGridLines: false,
  }
  //创建二进制对象写入转换好的字节流
  let tmpDown = new Blob([str2ab(XLSX.write(wb, wopts))], {
    type: 'application/octet-stream',
  })
  FileSaver.saveAs(tmpDown, excelName + '.xlsx')
}

/**
 * 导入Excel
 * @param file
 * @returns {boolean}
 */
export function importExcel(file, sheetNo) {
  let promise = new Promise((resolve, reject) => {
    // 导入
    // FileReader共有4种读取方法：
    // 1.readAsArrayBuffer(file) ：将文件读取为ArrayBuffer。
    // 2.readAsBinaryString(file) ：将文件读取为二进制字符串
    // 3.readAsDataURL(file) ：将文件读取为Data URL
    // 4.readAsText(file, [encoding]) ：将文件读取为文本，encoding缺省值为'UTF-8'
    var wb // 读取完成的数据
    var rABS = false // 是否将文件读取为二进制字符串
    //let obj = document.getElementById(file.uid);
    if (!file) {
      return
    }
    var reader = new FileReader()
    if (rABS) {
      reader.readAsArrayBuffer(file)
    } else {
      reader.readAsBinaryString(file)
    }
    var arr = []
    reader.onload = (e) => {
      var data = e.target.result
      if (rABS) {
        wb = XLSX.read(btoa(fixdata(data)), {
          // 手动转化
          type: 'base64',
        })
      } else {
        wb = XLSX.read(data, {
          type: 'binary',
        })
      }
      // wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
      // wb.Sheets[Sheet名]获取第一个Sheet的数据
      arr = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[sheetNo]])
      // console.log(JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])))
      // console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]))
      // return XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
      resolve(arr)
    }
    reader.onerror = function (e) {
      reject(arr)
    }
  })
  return promise
}

/**
 * 字符串转字符流
 * @param s
 * @returns {*}
 */
export function str2ab(s) {
  if (typeof ArrayBuffer !== 'undefined') {
    var buf = new ArrayBuffer(s.length)
    var view = new Uint8Array(buf)
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
    return buf
  } else {
    var buf = new Array(s.length)
    for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff
    return buf
  }
}

export default {
  export_table_to_excel,
  export_array_to_excel,
  export_json_to_excel,
  read,
  exportToExcel,
  importExcel,
}
