/*
 * @Author: Badguy
 * @Date: 2022-02-11 09:20:58
 * @LastEditTime: 2022-05-25 17:55:05
 * @LastEditors: your name
 * @Description: 表格用
 * have a nice day!
 */

import _ from 'lodash'
import * as XLSX from 'xlsx'
import XLSX_STYLE from 'xlsx-style'
import FileSaver from 'file-saver'
import { Message } from 'element-ui'

/**
 * @description: 表格行合并
 * @param {Object} config
 * @return {Array}
 */
export function mergeTableRow (config) {
  let data = config.data
  const { mergeColNames, firstMergeColNames, firstMerge } = config
  if (!mergeColNames || mergeColNames.length === 0) {
    return data
  }
  mergeColNames.forEach(m => {
    const mList = {}
    data = data.map((v, index) => {
      const rowVal = v[m]
      if (mList[rowVal] && mList[rowVal].newIndex === index) {
        const flag =
          firstMergeColNames.filter(f => {
            return f === m
          }).length !== 0
        const mcFlag =
          mergeColNames.filter(mc => {
            return mc === firstMerge
          }).length === 0
        if (
          (mcFlag && flag) ||
          (flag &&
            data[index][firstMerge + '-span'] &&
            data[index][firstMerge + '-span'].rowspan === 1)
        ) {
          v[m + '-span'] = {
            rowspan: 1,
            colspan: 1,
          }
        } else {
          data[mList[rowVal]['index']][m + '-span'].rowspan++
          v[m + '-span'] = {
            rowspan: 0,
            colspan: 0,
          }
          mList[rowVal]['num']++
          mList[rowVal]['newIndex']++
        }
      } else {
        mList[rowVal] = { num: 1, index: index, newIndex: index + 1 }
        v[m + '-span'] = {
          rowspan: 1,
          colspan: 1,
        }
      }
      return v
    })
  })
  return data
}

// 表格单元格class设置
export function commonTableCellClass ({ row, column, rowIndex, columnIndex }) {
  const classes = []
  if (['actualDepartureTime', 'actualLandingTime'].includes(column.property)) {
    classes.push('pre-line')
  }
  return classes
}

// 获取对应时区的时间
export function timeInZone (date, timeZone = 0, local = 8) {
  if (!(date instanceof Date)) {
    if (typeof date === 'string' && date.length) {
      date = new Date(date)
    } else {
      return ''
    }
  }

  function formatDate (num) {
    return num < 10 ? '0' + num : num
  }
  const time = date.getTime() + (timeZone - local) * 60 * 60 * 1000
  date.setTime(time)
  const year = date.getFullYear()
  const month = formatDate(date.getMonth() + 1)
  const day = formatDate(date.getDate())
  const hour = formatDate(date.getHours())
  const minute = formatDate(date.getMinutes())
  const second = formatDate(date.getSeconds())
  return `${year}-${month}-${day} ${hour}:${minute}:${second}`
}

// // 表格添加过滤条件
// export function setTableFilters(tableData, filterKeys) {
//   const tempSets = {}
//   const result = {}
//   filterKeys.forEach(key => {
//     tempSets[key] = new Set()
//   })
//   tableData.forEach(item => {
//     Object.keys(tempSets).forEach(key => {
//       (item[key] ?? '') !== '' && tempSets[key].add(item[key])
//     })
//   })
//   Object.keys(tempSets).forEach(key => {
//     result[key] = _.sortBy(
//       [...tempSets[key]].map(value => ({
//         text: value,
//         value
//       })),
//       ['value']
//     )
//   })
//   return result
// }

// 表格添加过滤条件
export function setTableFilters (tableData, filters) {
  const tempSets = {}
  Object.keys(filters).forEach(key => {
    tempSets[key] = new Set()
  })
  tableData.forEach(item => {
    Object.keys(tempSets).forEach(key => {
      ; (item[key] ?? '') !== '' && tempSets[key].add(String(item[key]))
    })
  })
  Object.keys(tempSets).forEach(key => {
    filters[key] = _.orderBy(
      [...tempSets[key]].map(value => ({
        text: value,
        value,
      })),
      o => o.value
    )
  })
}

function devideGroup (cellName) {
  const stringArray = cellName.split('')
  const length = stringArray.length
  let index = 0
  for (let i = 0; i < length; i++) {
    if (isNaN(parseInt(stringArray[i]))) {
      index += stringArray[i].charCodeAt(0) - 'A'.charCodeAt(0) + i * 26
    } else {
      return {
        columnIndex: index,
        rowIndex: Number(stringArray.slice(i).join('')) - 1,
      }
    }
  }
}

export function exportToExcel (table, tableName, fileName, headerRowNumber = 1) {
  try {
    // 设置了列的fixed属性后会有两个table元素，导出数据会重复，需要去掉一个table
    const fixedTable = table.querySelector('.el-table__fixed')
    fixedTable && table.removeChild(fixedTable)
    // 自定义的表头里包含筛选，直接导出会把筛选的下拉数据也写到表头单元格里，需要先去掉筛选弹出框
    const tableHeaderCellPopovers = table.querySelectorAll(
      '.table-header-cell-popover'
    )
    tableHeaderCellPopovers.forEach(node => {
      if (node.querySelector('.el-popover')) {
        node.removeChild(node.querySelector('.el-popover'))
      }
    })
    // 生成要导出的xlsx数据，raw: true表示不使用excel的格式解析，输出为纯文本，sheet设置xlsx这一页的标题
    const tableBook = XLSX.utils.table_to_book(table, {
      raw: true,
      sheet: tableName,
    })
    // 计算每一列的单元格的最大宽度（包含表头），单元格的key为'A12'、'AA2'等，和excel里一致
    const xlsxDatas = tableBook.Sheets[tableName]
    const columnWidths = []
    const reg = /^[A-Z]+([\d]+$)/
    for (const cellName in xlsxDatas) {
      const match = cellName.match(reg)
      if (match) {
        const cellValue = xlsxDatas[cellName].v
        const { columnIndex, rowIndex } = devideGroup(cellName)
        const cellWidth = Math.max(
          ...cellValue
            .toString()
            .split('\n')
            .map(cellRow =>
              cellRow.split('').reduce((pre, curr) => {
                const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
                return pre + letterSize
              }, 0)
            )
        )
        if (
          (!columnWidths[columnIndex] && cellWidth > 0) ||
          cellWidth > columnWidths[columnIndex]
        ) {
          columnWidths[columnIndex] = cellWidth
        }
        let cellStyle = {
          alignment: {
            horizontal: 'center',
            vertical: 'center',
            wrapText: true,
          },
        }
        if (rowIndex < headerRowNumber) {
          const borderStyle = {
            style: 'medium',
            color: {
              rgb: 'FFFFFF',
            },
          }
          cellStyle = {
            ...cellStyle,
            border: {
              top: borderStyle,
              right: borderStyle,
              bottom: borderStyle,
              left: borderStyle,
            },
            font: {
              color: {
                rgb: 'FFFFFF',
              },
            },
            fill: {
              fgColor: {
                rgb: '3366FF',
              },
            },
          }
        } else {
          cellStyle.alignment.horizontal = 'left'

          const isNumber = /^[^0]/.test(cellValue) && !isNaN(parseFloat(cellValue)) && isFinite(cellValue)
          if (isNumber) {
            xlsxDatas[cellName] = {
              ...xlsxDatas[cellName],
              t: 'n',
              z: '0',
              v: Number(cellValue),
            }
          }
          const isPercentage = /^\d+(\.\d+){0,1}\%$/.test(cellValue)
          if (isPercentage) {
            xlsxDatas[cellName] = {
              ...xlsxDatas[cellName],
              t: 'n',
              z: '0.00%',
              v: parseFloat(cellValue),
            }
          }
          // const date = '\\d{4}\\-\\d{2}\\-\\d{2}'
          // const time = '\\d{2}\\:\\d{2}\:\\d{2}'
          // const dateReg = new RegExp(`^${date}$`)
          // const timeReg = new RegExp(`^${time}$`)
          // const datetimeReg = new RegExp(`^${date} ${time}$`)
          // const isDate = dateReg.test(cellValue)
          // const isTime = timeReg.test(cellValue)
          // const isDatetime = datetimeReg.test(cellValue)
          // if (isDate) {
          //   xlsxDatas[cellName] = {
          //     ...xlsxDatas[cellName],
          //     t: 'd',
          //     z: 'yyyy-MM-dd',
          //     v: new Date(cellValue),
          //   }
          // }
          // if (isTime) {
          //   xlsxDatas[cellName] = {
          //     ...xlsxDatas[cellName],
          //     t: 'd',
          //     z: 'HH:mm:ss',
          //     v: new Date(cellValue),
          //   }
          // }
          // if (isDatetime) {
          //   xlsxDatas[cellName] = {
          //     ...xlsxDatas[cellName],
          //     t: 'd',
          //     z: 'yyyy-MM-dd HH:mm:ss',
          //     v: new Date(cellValue),
          //   }
          // }
        }
        xlsxDatas[cellName].s = cellStyle
      }
    }
    xlsxDatas['!cols'] = columnWidths.map(width => ({
      wch: width + 2,
    }))
    const tableWrite = XLSX_STYLE.write(tableBook, {
      bookType: 'xlsx',
      bookSST: true,
      type: 'buffer',
      cellStyles: true,
    })
    FileSaver.saveAs(
      new Blob([tableWrite], { type: 'application/octet-stream' }),
      fileName
    )
  } catch (error) {
    Message.error(error.message)
  }
}
