<template>
  <div class="flex h-full">
    <div id="luckysheet" class="flex-1"></div>

    <div class="w-[400px] h-full bg-white">
      <p class="pl-2 text-lg font-bold leading-[40px] bg-slate-200">标注配置</p>

      <el-form size="small" label-width="5em" class="comment-form pl-2 pr-2 pt-2 pb-2 border-b-2">
        <el-row :gutter="10">
          <el-col :span="12">
            <el-form-item label="区域类型">
              <el-select v-model="formState.excelAreaType"></el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="区域别称">
              <el-input v-model="formState.excelAreaNicname"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-button type="primary" @click="setAreaMark('data')">设置数据区</el-button>
            <el-button type="primary" @click="setAreaMark('head')">设置标题区</el-button>
          </el-col>
        </el-row>
      </el-form>

      <div class="border-b-2 p-2 leading-7 text-sm">
        <p class="font-bold">当前标记数据区域：</p>
        <p class="text-slate-600">
          选择区域：{{
            getRangetxt(
              cachAreaMark.beginRow,
              cachAreaMark.endRow,
              cachAreaMark.beginColum,
              cachAreaMark.endColum
            )
          }}
        </p>
        <p class="text-slate-600">区域类型：{{ cachAreaMark.excelAreaType || '--' }}</p>
        <p class="text-slate-600">区域别称：{{ cachAreaMark.excelAreaNicname || '--' }}</p>
        <vxe-table
          :row-config="{ isCurrent: true }"
          border
          :data="cachHeadAreaData"
          size="mini"
          height="200"
        >
          <vxe-column title="title" field="title"></vxe-column>
          <vxe-column title="单元格" field="cell" width="90">
            <template #default="{ row }">
              {{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
            </template>
          </vxe-column>
        </vxe-table>
        <el-button type="primary" size="small" @click="resetCachArea()">重置选区</el-button>
        <el-button type="primary" size="small" @click="resetCachHeadArea">重置标题区</el-button>
        <el-button type="primary" size="small" @click="saveAreaMark">保存</el-button>
      </div>

      <div class="p-2 text-sm">
        <p class="font-bold">已标记记录：</p>
        <vxe-table
          @cell-click="cellClick"
          :row-config="{ isCurrent: true }"
          border
          :data="areaList"
          size="mini"
          height="200"
        >
          <vxe-column title="sheet" field="sheetNum" width="60"></vxe-column>
          <vxe-column title="别称" field="excelAreaNicname"></vxe-column>
          <vxe-column title="区域" field="area" width="90">
            <template #default="{ row }">
              {{ getRangetxt(row.beginRow, row.endRow, row.beginColum, row.endColum) }}
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, reactive, unref, computed } from 'vue'
import LuckyExcel from 'luckyexcel'
import {
  areaMarksColor,
  authorityConfig,
  cellRightClickConfig,
  sheetRightClickConfig,
  showsheetbarConfig,
  showstatisticBarConfig
} from '@/constants/excelConfig'
import { flatten } from 'lodash-es'
import { useCommentExcel } from '@/stores/commentExcel'
import { storeToRefs } from 'pinia'
import { isFunction } from '@/utils/is'
import { ElMessage, ElMessageBox } from 'element-plus'
import { addExcelArea, getExcelAreaByFileId } from '@/api/excel'
import type { Recordable } from '@/types/global'
import { getRangetxt } from '@/utils/excel'

const commentExcelStore = useCommentExcel()
const { getFileInfo } = storeToRefs(commentExcelStore)
const formState = reactive({
  excelAreaId: '',
  fileId: '',
  sheetNum: 0,
  beginRow: '',
  beginColum: '',
  endRow: '',
  endColum: '',
  excelAreaType: '',
  excelAreaNicname: ''
})

/**
 * 存储在本地的区域标记
 * locaExcelAreaMarks = {
 *  '0': [formState, formState]
 * }
 */
const locaExcelAreaMarks: Recordable = reactive({})
const areaList = computed(() => flatten(Object.values(locaExcelAreaMarks)))

const initExcelAreaMarksKey = (len) => {
  Array.from({ length: len }).forEach((item, index) => {
    Reflect.set(locaExcelAreaMarks, index, [])
  })
}

const setSheetAuthority = (exportJson: any) => {
  exportJson.sheets.forEach((sheet: any) => {
    // 工作表格权限
    sheet.config.authority = authorityConfig
    // 单元格锁定
    sheet.celldata.forEach((item: any) => {
      item.v.lo = 1
    })
  })
}

const cellClick = ({ row }) => {
  // 判断是否是当前sheet页标记
  const sheet = window.luckysheet.getSheet()
  if (sheet.order !== row.sheetNum) {
    window.luckysheet.setSheetActive(row.sheetNum)
  }
  window.luckysheet.scroll({
    targetRow: row.beginRow,
    targetColumn: row.beginColum
  })
  setTimeout(() => {
    window.luckysheet.setRangeShow({
      row: [row.beginRow, row.endRow],
      column: [row.beginColum, row.endColum]
    })
  }, 100)
}

const cachAreaMark = reactive<Recordable>({})
const cachHeadAreaData = computed(() => cachAreaMark?.excelAreaTitle || [])
const setAreaMark = async (type: 'data' | 'head' = 'data') => {
  if (type === 'data') {
    /**
     * 判断是否有未保存的区域
     * 如果有未保存的标记 -> 提示用户，是否覆盖
     */
    if (cachAreaMark.beginRow !== '' && cachAreaMark.beginRow !== undefined) {
      await ElMessageBox.confirm('检测到未保存的标记，是否在覆盖当前标记区域？', '提示消息', {
        confirmButtonText: '覆盖',
        cancelButtonText: '取消'
      })
      resetCachArea(() => {
        // 设置当前选区
        window.luckysheet.setRangeShow({
          row: [formState.beginRow, formState.endRow],
          column: [formState.beginColum, formState.endColum]
        })
      })
    }

    Object.assign(cachAreaMark, unref(formState))
    // 设置完成之后重置表单
    Object.assign(formState, {
      excelAreaType: '',
      excelAreaNicname: ''
    })
  } else {
    // 判断是否在同一sheet
    if (formState.sheetNum !== cachAreaMark.sheetNum) {
      return ElMessage.error('请在同一sheet页中选择数据！')
    }

    /**
     * 组装数据
     * 判断选择的 head区域 是否在数据区域 内部
     * 判断是否有重复的单元格添加，如有重复无需添加此单元格
     */
    const result = []
    const rangeData = window.luckysheet.getRangeValue()
    console.log('rangeData', rangeData)
    const { beginColum, beginRow, endColum, endRow } = formState
    for (let i = beginRow, r = 0; i <= endRow; i++) {
      for (let k = beginColum, c = 0; k <= endColum; k++) {
        result.push({
          title: rangeData[r][c].v || rangeData[r][c].ct.s[0].v,
          sheet: formState.sheetNum,
          row: i,
          colum: k
        })
        c++
      }
      r++
    }

    // 合并组装的表头区域数据
    cachAreaMark.excelAreaTitle
      ? cachAreaMark.excelAreaTitle.push(...result)
      : (cachAreaMark.excelAreaTitle = result)
  }

  setTimeout(() => {
    // 设置区域颜色
    window.luckysheet.setRangeFormat('bg', areaMarksColor[type])
  }, 100)
}
const resetCachAreaState = () => {
  // 删除 excelAreaTitle 属性
  delete cachAreaMark.excelAreaTitle
  // 重置 其他属性
  Object.assign(cachAreaMark, {
    excelAreaId: '',
    fileId: '',
    sheetNum: 0,
    beginRow: '',
    beginColum: '',
    endRow: '',
    endColum: '',
    excelAreaType: '',
    excelAreaNicname: ''
  })
}
const resetCachArea = (fn?: Function) => {
  // 清除区域颜色
  window.luckysheet.setRangeShow(
    {
      row: [cachAreaMark.beginRow, cachAreaMark.endRow],
      column: [cachAreaMark.beginColum, cachAreaMark.endColum]
    },
    {
      show: false,
      success: () => {
        window.luckysheet.setRangeFormat('bg', areaMarksColor['default'])
        resetCachAreaState()
        fn && fn()
      }
    }
  )
}
const resetCachHeadArea = () => {
  // 清除标题区域颜色 -> 设置成数据区域颜色
  window.luckysheet.setRangeShow(
    {
      row: [cachAreaMark.beginRow, cachAreaMark.endRow],
      column: [cachAreaMark.beginColum, cachAreaMark.endColum]
    },
    {
      show: false,
      success: () => {
        window.luckysheet.setRangeFormat('bg', areaMarksColor['data'])
        // 删除 excelAreaTitle 属性
        delete cachAreaMark.excelAreaTitle
      }
    }
  )
}
const saveAreaMark = async () => {
  cachAreaMark.fileId = getFileInfo.value.orderFileId
  const { data } = await addExcelArea(cachAreaMark)
  // 接口保存成功之后，保存一份在本地 locaExcelAreaMarks
  locaExcelAreaMarks[cachAreaMark.sheetNum].push(data.result)
  resetCachAreaState()
}

const queryArea = async () => {
  const { data } = await getExcelAreaByFileId(getFileInfo.value.orderFileId)
  data.result.forEach((item) => locaExcelAreaMarks[item.sheetNum].push(item))
}

const loadExcel = () => {
  LuckyExcel.transformExcelToLuckyByUrl(
    '/api/sys/static/' + getFileInfo.value.mergeFilePath,
    new Date().getTime() + '.xlsx',
    async (exportJson: any) => {
      console.log('---exportJson', exportJson)

      initExcelAreaMarksKey(exportJson.sheets.length)

      // 查询区域标记
      await queryArea()

      setSheetAuthority(exportJson)
      isFunction(window?.luckysheet?.destroy) && window.luckysheet.destroy()

      window.luckysheet.create({
        container: 'luckysheet', //luckysheet is the container id
        showinfobar: false,
        showtoolbar: false,
        showsheetbar: false,
        showsheetbarConfig,
        cellRightClickConfig,
        sheetRightClickConfig,
        showstatisticBarConfig,
        data: exportJson.sheets,
        title: exportJson.info.name,
        userInfo: exportJson.info.name.creator,
        hook: {
          sheetMouseup: (c: any, p: any, sheet: any, status: any) => {
            console.log('c,p,sheet,status-----', c, p, sheet, status)
            // 选择的区域
            if (sheet.luckysheet_select_save.length === 1) {
              const [selected] = sheet.luckysheet_select_save
              const [beginRow, endRow] = selected.row
              const [beginColum, endColum] = selected.column

              formState.sheetNum = +sheet.order
              formState.beginColum = beginColum
              formState.beginRow = beginRow
              formState.endColum = endColum
              formState.endRow = endRow
            }
          },
          sheetActivate: () => {},
          workbookCreateAfter: () => {
            // 判断本地是否有第一个sheet页的标记
            if (locaExcelAreaMarks[0].length) {
              locaExcelAreaMarks[0].forEach((item) => {
                // 设置数据区标记
                window.luckysheet.menuButton.customUpdateFormat(
                  null,
                  'bg',
                  areaMarksColor['data'],
                  item.beginRow,
                  item.endRow,
                  item.beginColum,
                  item.endColum
                )

              })
            }
          }
        }
      })
    }
  )
}
onMounted(() => {
  loadExcel()
})
onUnmounted(() => {
  isFunction(window?.luckysheet?.destroy) && window.luckysheet.destroy()
})
</script>
<style lang="scss" scoped>
.comment-form {
  .el-form-item--small {
    margin-bottom: 10px;
  }
}
</style>
