import { cloneDeep } from 'lodash'
import { exportWordDocx, getBase64Sync } from './exportWord'
import { baseURL } from './http'
import { resJiLianFu } from './history'
import {
  arrangeImages,
  calculateRowCharLines,
  numberToChinese,
  removeHtmlTags
} from './exportWordUtils'

export enum EXPORT_WORD_ENUM {
  /** 借用藏品点交凭证 */
  BORROW = 1,
  /** 藏品馆内提退凭单 */
  HALL_PUT_BACK = 2,
  /** 分库藏品提退出入库记录单 */
  SUB_PUT_BACK = 3,
  /** 分库藏品入库记录单 */
  SUB_PUT_IN = 4,
  /** 入馆凭证 */
  VOUCHER = 5,
  /** 藏品图片及相关数字化信息使用申请单 */
  FORM_FOR_DIGITAL = 6,
  /** 藏品卡片 */
  COLLECTION_CARD = 7
}

const WORD_FILE_NAME_MAP = {
  [EXPORT_WORD_ENUM.BORROW]: {
    fileName: '义乌市博物馆借用藏品点交凭证',
    templateName: '1.docx'
  },
  [EXPORT_WORD_ENUM.HALL_PUT_BACK]: {
    fileName: '义乌市博物馆藏品馆内提退凭单',
    templateName: '2.docx',
    // 每个字段单行最大字符数
    perLine: {
      num: 9,
      name: 24,
      pcsUnit: 4,
      rtf: 6
    },
    row: {
      // 首页最大行数
      maxRowFirstPage: 3,
      // 尾页最大行数
      maxRowLastPage: 6,
      // 每页最大行数
      maxRowPage: 8,
      // 首页单行最大字符行数
      maxFirstCharLine: 20,
      // 尾页单行最大字符行数
      maxLastCharLine: 18,
      // 每页最大字符行数
      maxCharLine: 26,
      // 表格每行最小字符行数
      minRowCharLine: 3
    }
  },
  [EXPORT_WORD_ENUM.SUB_PUT_BACK]: {
    fileName: '义乌市博物馆分库藏品提退出入库记录单',
    templateName: '3.docx'
  },
  [EXPORT_WORD_ENUM.SUB_PUT_IN]: {
    fileName: '义乌市博物馆分库藏品入库记录单',
    templateName: '4.docx'
  },
  [EXPORT_WORD_ENUM.VOUCHER]: {
    fileName: '义乌市博物馆入馆凭证',
    templateName: '5.docx'
  },
  [EXPORT_WORD_ENUM.FORM_FOR_DIGITAL]: {
    fileName: '义乌市博物馆藏品图片及相关数字化信息使用申请单',
    templateName: '6.docx'
  },
  [EXPORT_WORD_ENUM.COLLECTION_CARD]: {
    fileName: '义乌市博物馆藏品卡片',
    templateName: '7.docx'
  }
}

/**
 * 计算表格数据的分页情况
 */
const calcTablePages = (rows: any[], config: (typeof WORD_FILE_NAME_MAP)[2]) => {
  if (rows.length === 0) return 0

  let totalPages = 0
  let currentPageRows: any[] = []
  let currentPageCharLines = 0
  let isFirstPage = true
  let isLastPage = false

  for (let i = 0; i < rows.length; i++) {
    const row = rows[i]
    const rowCharLines = calculateRowCharLines(row, config.perLine)

    currentPageCharLines += Math.max(rowCharLines, config.row.minRowCharLine)
    currentPageRows.push(row)

    // 判断是否超出首页
    if (isFirstPage && currentPageCharLines > config.row.maxFirstCharLine) {
      isFirstPage = false
      totalPages++
      currentPageCharLines -= config.row.maxFirstCharLine

      // 如果剩下行数还超出尾页最大行数，也先预处理
      if (currentPageCharLines > config.row.maxLastCharLine) {
        totalPages++
        currentPageCharLines -= config.row.maxLastCharLine
      }
    }

    // 确定当前页的限制
    const maxRows = isFirstPage
      ? config.row.maxRowFirstPage
      : isLastPage
      ? config.row.maxRowLastPage
      : config.row.maxRowPage

    const maxCharLines = isFirstPage
      ? config.row.maxFirstCharLine
      : isLastPage
      ? config.row.maxLastCharLine
      : config.row.maxCharLine

    // 检查是否换页
    const isPageFull = currentPageRows.length >= maxRows || currentPageCharLines >= maxCharLines

    if (isPageFull || i === rows.length - 1) {
      totalPages +=
        Math.floor(currentPageCharLines / maxCharLines) +
        (currentPageCharLines % maxCharLines > 0 ? 1 : 0)
      currentPageRows = []
      currentPageCharLines = 0
      isFirstPage = false
      isLastPage = i === rows.length - 1
    }
  }

  return totalPages
}

/**
 * 根据业务类型导出数据
 */
export const exportWordHandler = async (type: EXPORT_WORD_ENUM, data: Record<any, any>) => {
  let temp = cloneDeep(data)
  let page = 1
  const date = new Date()
  const item = WORD_FILE_NAME_MAP[type]

  temp.sizeUnit && (temp.sizeUnit = resJiLianFu(temp.sizeUnit))
  temp.qualityUnit && (temp.qualityUnit = resJiLianFu(temp.qualityUnit))
  temp.dictAge && (temp.dictAge = resJiLianFu(temp.dictAge))

  if (Array.isArray(temp.goods) && temp.goods.length) {
    for (let i = 0; i < temp.goods.length; i++) {
      const good = temp.goods[i]
      good.index = i + 1
      good.rtf && (good.rtf = removeHtmlTags(JSON.parse(good.rtf).txtArr[0].txt))
      good.thumb && (good.thumb = await getBase64Sync(baseURL + good.thumb))
      good.dictAge && (good.dictAge = resJiLianFu(good.dictAge))
      good.pcsUnit && (good.pcsUnit = resJiLianFu(good.pcsUnit))
      good.dictTexture3 && (good.dictTexture = resJiLianFu(good.dictTexture3))
      good.dictTorn && (good.dictTorn = resJiLianFu(good.dictTorn))
      good.source && (good.source = resJiLianFu(good.source))
    }
  } else {
    temp.goods = []
  }

  // @ts-ignore
  if (item.perLine) {
    // @ts-ignore
    page = calcTablePages(temp.goods, item)
  }

  switch (type) {
    case EXPORT_WORD_ENUM.BORROW:
      temp = {
        ...temp,
        group: numberToChinese(temp.goods.length),
        num: numberToChinese(
          temp.goods.reduce((sum: number, item: any) => sum + (item.pcs || 0), 0)
        ),
        page: numberToChinese(page)
      }
      break
    case EXPORT_WORD_ENUM.HALL_PUT_BACK:
      temp = {
        ...temp,
        year: date.getFullYear(),
        group: numberToChinese(temp.goods.length),
        page: numberToChinese(page)
      }
      break
    case EXPORT_WORD_ENUM.VOUCHER:
      temp = {
        ...temp,
        year: date.getFullYear(),
        month: date.getMonth() + 1,
        day: date.getDay(),
        group: numberToChinese(temp.goods.length),
        page: numberToChinese(page)
      }
      break
    case EXPORT_WORD_ENUM.FORM_FOR_DIGITAL:
      temp = {
        ...temp,
        year: date.getFullYear(),
        month: date.getMonth() + 1,
        day: date.getDay()
      }
      break
    case EXPORT_WORD_ENUM.COLLECTION_CARD:
      temp.imagePages = await arrangeImages(temp.imagePages)
      break
  }

  exportWordDocx(`/templates/${item.templateName}`, temp, item.fileName)
}
