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

    <el-scrollbar height="100%">
      <div class="w-[420px] h-full bg-white">
        <p class="pl-2 text-lg font-bold leading-[40px] bg-slate-200">标注配置</p>
        <SetArea @success="onSaveSuccess" />
        <!-- <el-form
          ref="settingForm"
          size="small"
          :rules="rules"
          :model="formState"
          label-width="6em"
          class="comment-form pl-2 pr-2 pt-2 pb-2 border-b-2"
        >
          <el-row :gutter="10">
            <el-col :span="24">
              <el-form-item label="区域别称" prop="excelAreaNicname">
                <el-input v-model="formState.excelAreaNicname" clearable></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="区域类型" prop="excelAreaType">
                <el-select v-model="formState.excelAreaType" clearable>
                  <template v-for="item in areaTypeSelectOption" :key="item.value">
                    <el-option :label="item.label" :value="item.value"></el-option>
                  </template>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="循环体间隔" prop="checkNumber">
                <el-input type="number" v-model="formState.checkNumber" clearable></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="标题区作为数据" prop="oneself" label-width="100px">
                <el-checkbox true-label="Y" false-label="N" v-model="formState.oneself"
                  >是</el-checkbox
                >
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="标题参与循环" prop="checkSelf" label-width="100px">
                <el-checkbox true-label="Y" false-label="N" v-model="formState.checkSelf"
                  >是</el-checkbox
                >
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-button-group class="mr-2">
                <el-button type="primary" @click="setAreaMark('data')">设置数据区</el-button>
                <el-button type="primary" @click="setAreaMark('head')">设置标题区</el-button>
              </el-button-group>
              <el-button-group>
                <el-button type="primary" @click="setAreaMark('attch')">设置附加信息</el-button>
                <el-button type="primary" @click="setAreaMark('attch_head')"
                  >设置附加别称</el-button
                >
                <el-button type="primary" @click="setAreaMark('attch_title')"
                  >设置附加标题</el-button
                >
              </el-button-group>
            </el-col>
          </el-row>
        </el-form>

        <div class="border-b-2 p-2 leading-7 text-sm">
          <el-descriptions
            class="current-area-mark"
            border
            title="当前标记数据区域"
            size="small"
            :column="2"
          >
            <el-descriptions-item label-class-name="descriptions-label" :span="2" label="区域别称">
              <template v-if="isEditCurrentArea">
                <el-input v-model="currentAreaMark.excelAreaNicname" size="small"></el-input>
              </template>
              <template v-else>
                {{ currentAreaMark.excelAreaNicname || '--' }}
              </template>
            </el-descriptions-item>
            <el-descriptions-item label-class-name="descriptions-label" label="标记区域">
              {{
                getRangetxt(
                  currentAreaMark.beginRow,
                  currentAreaMark.endRow,
                  currentAreaMark.beginColum,
                  currentAreaMark.endColum
                )
              }}
            </el-descriptions-item>
            <el-descriptions-item label-class-name="descriptions-label" label="区域类型">
              <template v-if="isEditCurrentArea">
                <el-select
                  style="width: 80px"
                  size="small"
                  v-model="currentAreaMark.excelAreaType"
                  clearable
                >
                  <template v-for="item in areaTypeSelectOption" :key="item.value">
                    <el-option :label="item.label" :value="item.value"></el-option>
                  </template>
                </el-select>
              </template>
              <template v-else>
                {{ getAreaTypeText(currentAreaMark.excelAreaType) }}
              </template>
            </el-descriptions-item>

            <el-descriptions-item label-class-name="descriptions-label" label="循环体间隔">
              <template v-if="isEditCurrentArea">
                <el-input
                  style="width: 80px"
                  size="small"
                  type="number"
                  v-model="currentAreaMark.checkNumber"
                ></el-input>
              </template>
              <template v-else>
                {{ currentAreaMark.checkNumber || '--' }}
              </template>
            </el-descriptions-item>
            <el-descriptions-item label-class-name="descriptions-label" label="标题作为数据">
              <el-checkbox
                true-label="Y"
                false-label="N"
                size="small"
                v-model="currentAreaMark.oneself"
                :disabled="!isEditCurrentArea"
                >是</el-checkbox
              >
            </el-descriptions-item>
            <el-descriptions-item label-class-name="descriptions-label" label="标题参与循环">
              <el-checkbox
                true-label="Y"
                false-label="N"
                size="small"
                v-model="currentAreaMark.checkSelf"
                :disabled="!isEditCurrentArea"
                >是</el-checkbox
              >
            </el-descriptions-item>
          </el-descriptions>

          <vxe-table
            class="mb-2 mt-2"
            :row-config="{ isCurrent: true }"
            border
            :data="currentAreaMark.excelAreaTitle"
            size="mini"
            height="200"
            :edit-config="{ trigger: 'click', mode: 'cell' }"
          >
            <vxe-column title="title" field="title" :edit-render="{}">
              <template #edit="{ row }">
                <el-input :disabled="isEditCurrentArea" v-model="row.title" size="small"></el-input>
              </template>
            </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>

          <p class="font-bold">附加信息</p>
          <vxe-table
            :data="currentAttchInfo.groupTitles"
            @cell-click="cellClick"
            border
            size="mini"
            max-height="200"
          >
            <vxe-column title="附加区域" field="area" width="120">
              <template #default="{ row }">
                {{ getRangetxt(row.row, row.row, row.colum, row.colum) }}
              </template>
            </vxe-column>
            <vxe-column title="附加title" field="attch_title">
              <template #default="{ row }">
                {{ row.title }}
              </template>
            </vxe-column>

            <vxe-column title="操作" field="action" width="80">
              <template #default="{ row, $rowIndex }">
                <el-link
                  style="font-size: 12px"
                  type="danger"
                  @click.stop="delAttchInfo(row, $rowIndex)"
                  >删除</el-link
                >
              </template>
            </vxe-column>
          </vxe-table>

          <vxe-table
            class="mb-2 mt-2"
            :row-config="{ isCurrent: true }"
            border
            :data="currentAttchInfo.areaTitles"
            size="mini"
            height="200"
            :edit-config="{ trigger: 'click', mode: 'cell' }"
          >
            <vxe-column title="title" field="title" :edit-render="{}">
              <template #edit="{ row }">
                <el-input :disabled="isEditCurrentArea" v-model="row.title" size="small"></el-input>
              </template>
            </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="saveAreaMark">保存</el-button>
          <el-button
            v-if="isEditCurrentArea"
            type="default"
            size="small"
            @click="resetCurrentAreaState(true)"
            >取消修改</el-button
          >
        </div> -->

        <div class="pt-2 pl-2 pr-2 pb-2 text-sm border-t-2 border-b-2">
          <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="55"></vxe-column>
            <vxe-column title="别称" field="excelAreaNicname"></vxe-column>
            <vxe-column title="类型" field="excelAreaType_dictText" width="60"></vxe-column>
            <vxe-column title="区域" field="area" width="80">
              <template #default="{ row }">
                {{ getRangetxt(row.beginRow, row.endRow, row.beginColum, row.endColum) }}
              </template>
            </vxe-column>
            <vxe-column title="操作" field="action" width="100">
              <template #default="{ row }">
                <el-link
                  class="mr-1"
                  style="font-size: 12px"
                  type="primary"
                  @click.stop="chooseConnect(row)"
                  >关联</el-link
                >
                <el-link class="mr-1" style="font-size: 12px" type="primary" @click="toModify(row)"
                  >修改</el-link
                >
                <el-link style="font-size: 12px" type="danger" @click="delAreaMark(row)"
                  >删除</el-link
                >
              </template>
            </vxe-column>
          </vxe-table>
        </div>

        <div class="p-2 text-sm">
          <p class="font-bold">区域关联信息</p>
          <vxe-table border :data="connectList" size="mini" height="200">
            <vxe-column title="关联名称" field="excelAreaId_dictText"></vxe-column>
            <vxe-column title="别关联名称" field="excelAreaBeId_dictText"></vxe-column>
            <vxe-column title="操作" field="action" width="80">
              <template #default="{ row, $rowIndex }">
                <!-- <el-link style="font-size: 12px" type="primary" @click="toModifyConnect(row)"
                  >修改</el-link
                > -->
                <el-link style="font-size: 12px" type="danger" @click="delConnect(row, $rowIndex)"
                  >删除</el-link
                >
              </template>
            </vxe-column>
          </vxe-table>
        </div>

        <el-button type="primary" size="small" @click="toRun">执行解析</el-button>
      </div>
    </el-scrollbar>

    <vxe-modal
      width="600"
      @hide="chooseConnectOnHide"
      v-model="chooseVisible"
      title="选择被关联的区域"
      show-footer
    >
      <vxe-table ref="beConnectTable" border size="mini" :data="beConnectData" height="400">
        <vxe-column type="radio" width="40"></vxe-column>
        <vxe-column title="sheet" field="sheetNum" width="60"></vxe-column>
        <vxe-column title="别称" field="excelAreaNicname"></vxe-column>
        <vxe-column title="区域类型" field="excelAreaType_dictText" width="100"></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>

      <template #footer>
        <el-button type="primary" @click="confirmBeConnect">确认</el-button>
      </template>
    </vxe-modal>

    <vxe-modal v-model="connectVisible" width="700" title="关联信息配置" show-footer>
      <p>关联区域信息：{{ currentConnectInfo.excelAreaNicname }}</p>
      <p>被关联信息：{{ cachCurrentBeConnectInfo.excelAreaNicname }}</p>

      <vxe-table
        class="mt-2"
        size="mini"
        :data="connectConfigData"
        border
        height="400"
        ref="xTableConnect"
      >
        <vxe-column type="checkbox" width="40"></vxe-column>
        <vxe-column title="关联title" field="title"></vxe-column>
        <vxe-column title="被关联title" field="betitle">
          <template #default="{ row }">
            <el-select v-model="row.betitle" size="small" @change="(v) => changeBeConnect(v, row)">
              <template v-for="item in beConnectSelectOptions" :key="item.title">
                <el-option :value="item.title" :label="item.title"></el-option>
              </template>
            </el-select>
          </template>
        </vxe-column>
      </vxe-table>
      <template #footer>
        <el-button type="primary" @click="confirmConnect">确认</el-button>
      </template>
    </vxe-modal>

    <vxe-modal width="80%" title="解析结果" v-model="runResultVisible">
      <el-button @click="exportRunData">导出数据</el-button>
      <vxe-table
        ref="runDataTable"
        size="mini"
        show-overflow="tooltip"
        :data="runResultData"
        border
        height="500"
      >
        <vxe-column title="行号" field="sortNum" width="120"></vxe-column>
        <vxe-column title="数据区" field="数据区" width="120"></vxe-column>
        <template v-for="item in runResultTitle" :key="item">
          <vxe-column :title="item" :field="item" width="200"></vxe-column>
        </template>
      </vxe-table>
    </vxe-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, reactive, unref, computed, watch, nextTick } from 'vue'
import LuckyExcel from 'luckyexcel'
import SetArea from '../SetArea/SetArea.vue'
import {
  areaMarksColor,
  authorityConfig,
  cellRightClickConfig,
  sheetRightClickConfig,
  showsheetbarConfig,
  showstatisticBarConfig
} from '@/constants/excelConfig'
import { flatten, cloneDeep } from 'lodash-es'
import { useCommentExcel } from '@/stores/commentExcel'
import { storeToRefs } from 'pinia'
import { isFunction } from '@/utils/is'
import {
  ElLoading,
  ElMessage,
  ElMessageBox,
  type FormInstance,
  type FormItemRule
} from 'element-plus'
import {
  addExcelArea,
  addExcelAreaConnect,
  editExcelArea,
  excelMarkRun,
  getExcelAreaByFileId,
  getExcelConnectByFileId,
  removeExcelArea,
  removeExcelAreaConnect
} from '@/api/excel'
import type { Recordable } from '@/types/global'
import { getRangetxt, handleRangeTitle } from '@/utils/excel'
import type { VxeTableInstance } from 'vxe-table'
import { apiDictFindById, apiDictList } from '@/api/common'

const settingForm = ref<FormInstance>()
const rules = reactive({
  excelAreaNicname: [{ required: true, message: '请输入区域别称！', trigger: 'change' }],
  excelAreaType: [{ required: true, message: '请选择区域类型！', trigger: 'change' }],
  checkNumber: [
    {
      validator: (rule, value, cb) => {
        if (value <= 0) {
          cb(new Error('请输入正整数！'))
          return false
        }
        return true
      },
      trigger: 'change'
    }
  ]
})
const connectVisible = ref(false)
const xTableConnect = ref<VxeTableInstance>()
const beConnectTable = ref<VxeTableInstance>()
const luckysheet = (window as any).luckysheet
const commentExcelStore = useCommentExcel()
const { getFileInfo } = storeToRefs(commentExcelStore)
const connectList = ref<any[]>([])
const chooseVisible = ref(false)
const areaTypeSelectOption = ref<any[]>([])
const currentConnectInfo = reactive<Recordable>({
  excelAreaConnectId: '',
  excelAreaId: '',
  excelAreaBeId: '',
  connectFiled: [],
  beConnectFiled: [],
  fileId: ''
})
const runDataTable = ref<VxeTableInstance>()
const cachCurrentConnectInfo = reactive<Recordable>({})
const cachCurrentBeConnectInfo = reactive<Recordable>({})
const beConnectData = computed(() => {
  /**
   * 如果公共区域 和 附加区域关联 只能关联 数据区域
   *
   * 并且数据区不能关联数据区
   */
  if (cachCurrentConnectInfo.excelAreaType == 'data_area') {
    return areaList.value
      .filter((v) => v.excelAreaType != 'data_area')
      .filter((v: any) => v.excelAreaId != currentConnectInfo.excelAreaId)
  } else {
    return areaList.value
      .filter((v) => v.excelAreaType == 'data_area')
      .filter((v: any) => v.excelAreaId != currentConnectInfo.excelAreaId)
  }
})
const formState = reactive({
  // excelAreaId: '',
  fileId: '',
  sheetNum: 0,
  beginRow: '',
  beginColum: '',
  endRow: '',
  endColum: '',
  excelAreaType: '',
  excelAreaNicname: '',
  checkNumber: 1,
  oneself: 'N',
  checkSelf: 'N'
})

watch(
  () => formState.excelAreaType,
  (val) => {
    console.log('watch----val', val)
    formState.excelAreaNicname = val
      ? areaTypeSelectOption.value.find((v) => v.value == val).label +
        (areaList.value.filter((v) => v.excelAreaType == val).length + 1)
      : ''
  }
)
const isSetSheetMark = ref<any>([])
const initIsSetSheetMark = (length: number) => {
  isSetSheetMark.value = Array.from({ length }).fill(false)
}

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

const onSaveSuccess = (data: any) => {
  locaExcelAreaMarks[data.result['sheetNum']].push(data.result)
}
const initExcelAreaMarksKey = (len: number) => {
  Array.from({ length: len }).forEach((item, index) => {
    Reflect.set(locaExcelAreaMarks, index, [])
  })
}

const exportRunData = () => {
  runDataTable.value?.exportData({ type: 'csv' })
}

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 }) => {
  const sheetNum = row?.sheetNum || row.sheet
  const beginRow = row?.beginRow || row.row
  const beginColum = row?.beginColum || row.colum
  const endColum = row?.endColum || row.colum
  const endRow = row?.endRow || row.row
  // 判断是否是当前sheet页标记
  const sheet = luckysheet.getSheet()
  if (sheet.order != sheetNum) {
    luckysheet.setSheetActive(sheetNum)
  }
  luckysheet.scroll({
    targetRow: beginRow - 3 < 0 ? 0 : beginRow - 3,
    targetColumn: beginColum - 3 < 0 ? 0 : beginColum - 3
  })
  setTimeout(() => {
    luckysheet.setRangeShow({
      row: [beginRow, endRow],
      column: [beginColum, endColum]
    })
  }, 100)
}

const currentAreaMark = reactive<Recordable>({
  oneself: 'N',
  checkSelf: 'N',
  checkNumber: 1,
  excelAreaTitle: [],
  desGroups: [],
  titleArea: ''
})

const isEditCurrentArea = computed(() => !!currentAreaMark.excelAreaId)
const currentTitlesArea = ref<Recordable>([])
const currentAttchInfo = reactive({
  sheetNum: '',
  beginRow: '',
  beginColum: '',
  endRow: '',
  endColum: '',
  groupTitles: [],
  areaTitles: []
})

// 删除附加信息
const delAttchInfo = (row, index) => {
  currentAreaMark.desGroups.splice(index, 1)

  // 选中要删除的区域，设置颜色
  luckysheet.setRangeShow({
    row: [row.beginRow, row.endRow],
    column: [row.beginColum, row.endColum]
  })

  luckysheet.setRangeFormat('bg', areaMarksColor['data'])
}
const resetAttchInfo = () => {
  Object.assign(currentAttchInfo, {
    sheetNum: '',
    beginRow: '',
    beginColum: '',
    endRow: '',
    endColum: '',
    groupTitles: [],
    areaTitles: []
  })
}
const saveAttchInfo = () => {
  const res = Object.assign({}, currentAttchInfo)
  const haveAttch = res.beginRow != ''
  if (haveAttch) {
    // 判断是否有 groupTitles
    if (!res.groupTitles.length) {
      ElMessage.error('请设置附加信息的别称！')
      return false
    }
    Object.assign(currentAreaMark, { desGroups: currentAreaMark.desGroups.concat(res) })
  }
  return true
}

const setAreaMark = async (
  type: 'data' | 'head' | 'attch' | 'attch_head' | 'attch_title' = 'data'
) => {
  if (type === 'data') {
    /**
     * 判断是否有未保存的区域
     * 如果有未保存的标记 -> 提示用户，是否覆盖
     */

    // 验证表单
    await settingForm.value?.validate()

    if (currentAreaMark.beginRow !== '' && currentAreaMark.beginRow !== undefined) {
      try {
        await ElMessageBox.confirm('检测到未保存的标记，是否保存？', '提示消息', {
          confirmButtonText: '保存',
          cancelButtonText: '取消'
        })
        return saveAreaMark()
      } catch {
        if (currentAreaMark.excelAreaId) {
          currentAreaMark.excelAreaId = ''
          resetCurrentAreaState()
        } else {
          currentAreaMark.excelAreaId = ''
          resetCurrentArea(() => {
            // 设置当前选区
            luckysheet.setRangeShow({
              row: [formState.beginRow, formState.endRow],
              column: [formState.beginColum, formState.endColum]
            })
          })
        }
      }

      // resetCurrentArea(() => {
      //   // 设置当前选区
      //   luckysheet.setRangeShow({
      //     row: [formState.beginRow, formState.endRow],
      //     column: [formState.beginColum, formState.endColum]
      //   })
      // })
    }
    // console.log(formState)
    // debugger
    Object.assign(currentAreaMark, unref(formState))
    // 设置完成之后重置表单
    settingForm.value?.resetFields([
      'excelAreaType',
      'excelAreaNicname',
      'oneself',
      'checkSelf',
      'checkNumber'
    ])
  } else if (type === 'head') {
    if (currentAreaMark.excelAreaId) {
      return ElMessage.error('请先保存或取消正在修改的数据区域！')
    }
    if (!currentAreaMark.excelAreaNicname) {
      return ElMessage.error('请先设置数据区！')
    }
    // 判断是否在同一sheet
    if (formState.sheetNum !== currentAreaMark.sheetNum) {
      return ElMessage.error('请在同一sheet页中选择数据！')
    }

    /**
     * 组装数据
     * 判断选择的 head区域 是否在数据区域 内部
     * 判断是否有重复的单元格添加，如有重复无需添加此单元格
     */
    const rangeData = luckysheet.getRangeValue()
    console.log('rangeData', rangeData)
    const titles = handleRangeTitle(rangeData, unref(formState))
    console.log('titles', titles)

    currentTitlesArea.value.push({
      excelAreaId: '',
      excelAreaNicname: currentAreaMark.excelAreaNicname,
      sr: formState.beginRow,
      sc: formState.beginColum,
      er: formState.endRow,
      ec: formState.endColum
    })

    // 合并组装的表头区域数据
    if (currentAreaMark.excelAreaTitle?.length > 0) {
      const arr = [...titles, ...unref(currentAreaMark.excelAreaTitle)]

      // 合并，去重
      currentAreaMark.excelAreaTitle = uniqArrayObject(arr)
    } else {
      currentAreaMark.excelAreaTitle = titles
    }
  } else if (type === 'attch') {
    // 是否设置数据区
    if (!currentAreaMark.excelAreaNicname) {
      return ElMessage.error('请先设置数据区！')
    }
    const area = {
      sheetNum: formState.sheetNum,
      beginRow: formState.beginRow,
      beginColum: formState.beginColum,
      endRow: formState.endRow,
      endColum: formState.endColum,
      groupTitles: [],
      areaTitles: []
    }

    Object.assign(currentAttchInfo, area)
  } else if (type === 'attch_head') {
    // 验证是否在附加区域
    // 验证是否设置附加区域
    if (currentAttchInfo.beginRow == '') {
      return ElMessage.error('请先设置附加信息区域！')
    }

    const rangeData = luckysheet.getRangeValue()
    const groupTitles = handleRangeTitle(rangeData, unref(currentAttchInfo))
    Object.assign(currentAttchInfo, { groupTitles })
  } else if (type === 'attch_title') {
    // 验证是否在附加区域
    // 验证是否设置附加区域
    if (currentAttchInfo.beginRow == '') {
      return ElMessage.error('请先设置附加信息区域！')
    }

    const rangeData = luckysheet.getRangeValue()
    const areaTitles = handleRangeTitle(rangeData, unref(currentAttchInfo))
    console.log('areaTitles', areaTitles)
    Object.assign(currentAttchInfo, { areaTitles })
  }

  function uniqArrayObject(arr = []) {
    return arr.reduce((cur, pre, index) => {
      if (index == 0) {
        cur.push(pre)
      } else {
        const isDiff = cur.every((item) => {
          return (
            item.column != pre.column ||
            item.row != pre.row ||
            item.sheet != pre.sheet ||
            item.title != pre.title
          )
        })
        isDiff && cur.push(pre)
      }
      return cur
    }, [])
  }

  setTimeout(() => {
    // 设置区域颜色
    luckysheet.setRangeFormat('bg', areaMarksColor[type])
  }, 100)
}

const resetCurrentAreaState = (isedit: boolean = false) => {
  // 重置 其他属性
  const tmp: Recordable = {
    sheetNum: 0,
    beginRow: '',
    beginColum: '',
    endRow: '',
    endColum: '',
    excelAreaType: '',
    excelAreaNicname: '',
    excelAreaTitle: [],
    desGroups: [],
    titleArea: '',
    oneself: 'N',
    checkSelf: 'N',
    checkNumber: ''
  }
  isedit && (tmp.excelAreaId = '')
  currentTitlesArea.value = []
  resetAttchInfo()
  Object.assign(currentAreaMark, tmp)
}
const resetCurrentArea = (fn?: Function) => {
  // 清除区域颜色
  luckysheet.setRangeShow(
    {
      row: [currentAreaMark.beginRow, currentAreaMark.endRow],
      column: [currentAreaMark.beginColum, currentAreaMark.endColum]
    },
    {
      show: false,
      success: () => {
        luckysheet.setRangeFormat('bg', areaMarksColor['default'])
        resetCurrentAreaState()
        fn && fn()
      }
    }
  )
}

const hasRepeatValue = (data: any[], field: string) => {
  const datas = data.map((item) => item[field])
  const res = Array.from(new Set(datas))
  return res.length == datas.length
}
const saveAreaMark = async () => {
  if (!hasRepeatValue(currentAreaMark.excelAreaTitle, 'title')) {
    return ElMessage.error('有重复标题！请修改后保存！')
  }
  // 保存附加信息
  if (!saveAttchInfo()) {
    return
  }
  currentAreaMark.fileId = getFileInfo.value.orderFileId
  currentAreaMark.titleArea = JSON.stringify(unref(currentTitlesArea))
  // 如果有id 调用修改，否则调用新增
  const isEdit = !!currentAreaMark.excelAreaId
  const { data } = isEdit
    ? await editExcelArea(currentAreaMark)
    : await addExcelArea(currentAreaMark)
  // 接口保存成功之后，保存/更新 locaExcelAreaMarks
  if (isEdit) {
    const idx = locaExcelAreaMarks[cachAreaMark.sheetNum].findIndex(
      (v) => v.excelAreaId == cachAreaMark.excelAreaId
    )
    locaExcelAreaMarks[cachAreaMark.sheetNum].splice(idx, 1, cloneDeep(currentAreaMark))
  } else {
    locaExcelAreaMarks[currentAreaMark.sheetNum].push(data.result)
  }
  ElMessage.success('操作成功！')
  resetCurrentAreaState(true)
}

const cachAreaMark = reactive<Recordable>({})
const cachDelOtherSheetArea = reactive<Recordable>({})
const delAreaMark = async (row: any) => {
  // 判断当前区域是否关联了其他区域
  if (
    connectList.value.find(
      (v) => row.excelAreaId == v.excelAreaId || row.excelAreaId == v.excelAreaBeId
    )
  ) {
    return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息，请先删除关联信息之后再做修改！')
  }

  if (currentAreaMark.excelAreaId == row.excelAreaId) {
    resetCurrentAreaState(true)
  }
  // 调用接口删除
  await removeExcelArea(row.excelAreaId)
  const sheet = luckysheet.getSheet()
  /**
   * 如果在本sheet那么直接删除，并且改变区域颜色
   * 如果不在当前sheet，保存删除的数据，在切换sheet的hook中删除颜色
   */
  if (row.sheetNum == sheet.order) {
    const range: Recordable = {
      row: [row.beginRow, row.endRow],
      column: [row.beginColum, row.endColum]
    }
    luckysheet.setRangeShow(range)
    setTimeout(() => {
      luckysheet.setRangeFormat('bg', areaMarksColor['default'])
    }, 100)
  } else {
    // 保存本地
    if (!Reflect.has(cachDelOtherSheetArea, row.sheetNum)) {
      cachDelOtherSheetArea[row.sheetNum] = []
    }
    cachDelOtherSheetArea[row.sheetNum].push(row)
  }

  // 删除本地标记 locaExcelAreaMark[row.sheetNum] 对应的区域
  const index = locaExcelAreaMarks[row.sheetNum].findIndex(
    (item: any) => item.excelAreaId == row.excelAreaId
  )
  locaExcelAreaMarks[row.sheetNum].splice(index, 1)
}
const toModify = (row) => {
  // 判断当前区域是否关联了其他区域
  if (
    connectList.value.find(
      (v) => row.excelAreaId == v.excelAreaId || row.excelAreaId == v.excelAreaBeId
    )
  ) {
    return ElMessage.warning('当前区域绑定与其他区域绑定了关联信息，请先删除关联信息之后再做修改！')
  }

  Object.assign(cachAreaMark, cloneDeep(row))
  Object.assign(currentAreaMark, row)
  // Object.assign(currentAttchInfo)

  currentTitlesArea.value = JSON.parse(currentAreaMark.titleArea)
}
const queryArea = async () => {
  const { data } = await getExcelAreaByFileId(getFileInfo.value.orderFileId)
  data.result.forEach((item: any) => locaExcelAreaMarks[item.sheetNum || 0].push(item))
}
const confirmConnect = () => {
  /**
   * 1. 验证是否选择了要关联的title
   * 2. 验证选择的title是否有被关联的title
   * 3. 添加关联关系
   */

  const list = xTableConnect.value?.getCheckboxRecords()
  if (!list?.length) {
    if (
      cachCurrentConnectInfo.excelAreaType == 'attach_area' ||
      cachCurrentBeConnectInfo.excelAreaType == 'attach_area'
    ) {
      return ElMessage.warning('请选择关联的字段！')
    }
    addConnect([])
    return
  }

  try {
    list.forEach((item) => {
      if (!item.betitle) {
        throw new Error('请选择被关联的title！！')
      }
    })
  } catch (e: any) {
    ElMessage.warning(e.message)
  }

  addConnect(list)
}
const addConnect = async (list: any) => {
  list.forEach((item: any) => {
    currentConnectInfo.connectFiled.push({
      title: item.title,
      sheet: item.sheet,
      row: item.row,
      colum: item.colum
    })

    currentConnectInfo.beConnectFiled.push({
      title: item.betitle,
      sheet: item.besheet,
      row: item.berow,
      colum: item.becolum
    })
  })
  currentConnectInfo.fileId = getFileInfo.value.orderFileId

  const { data } = await addExcelAreaConnect(currentConnectInfo)

  if (!data?.success) {
    ElMessage.error(data?.message || '操作失败！')
    return
  }
  ElMessage.success('添加成功！')
  connectVisible.value = false
  // 添加成功 手动更新页面数据
  connectList.value.push(data.result)
}
const chooseConnect = (row: any) => {
  currentConnectInfo.excelAreaId = row.excelAreaId
  Object.assign(cachCurrentConnectInfo, unref(row))
  chooseVisible.value = true
}

const connectConfigData = ref([])
const beConnectSelectOptions = computed(
  () =>
    areaList.value.find((v: any) => v.excelAreaId == currentConnectInfo.excelAreaBeId)
      ?.excelAreaTitle || []
)
watch(connectVisible, (val) => {
  if (val) {
    const titles = areaList.value.find((v: any) => v.excelAreaId == currentConnectInfo.excelAreaId)
      ?.excelAreaTitle

    connectConfigData.value = titles.map((item: any) => {
      return {
        title: item.title,
        sheet: item.sheet,
        row: item.row,
        colum: item.colum,
        betitle: '',
        berow: '',
        becolum: '',
        besheet: ''
      }
    })
  }
})
const changeBeConnect = (v: string, row: any) => {
  const option = beConnectSelectOptions.value.find((item: any) => item.title == v)
  console.log('option', option)
  row.becolum = option.colum
  row.besheet = option.sheet
  row.berow = option.row
  row.betitle = option.title
}
const confirmBeConnect = () => {
  const data = beConnectTable.value?.getRadioRecord()
  if (!data) {
    return ElMessage.warning('请选择有效数据！')
  }
  Object.assign(cachCurrentBeConnectInfo, unref(data))
  currentConnectInfo.excelAreaBeId = data.excelAreaId

  // 如果是附加区域，那么直接关联
  if (
    cachCurrentConnectInfo.excelAreaType == 'attach_area' ||
    data.excelAreaType == 'attach_area'
  ) {
    return addConnect([]).then(() => {
      chooseVisible.value = false
    })
  }

  // 打开关联弹窗。
  chooseVisible.value = false
  connectVisible.value = true
}
const chooseConnectOnHide = () => {
  Object.assign(currentConnectInfo, {
    // excelAreaConnectId: '',
    // excelAreaId: '',
    // excelAreaBeId: '',
    connectFiled: [],
    beConnectFiled: []
    // fileId: ''
  })
}
const delConnect = async (row: any, index: number) => {
  const { data } = await removeExcelAreaConnect(row.excelAreaConnectId)
  if (data?.success) {
    ElMessage.success('删除成功！')
  }
  // 手动删除
  connectList.value.splice(index, 1)
}
const queryConnectList = async () => {
  const { data } = await getExcelConnectByFileId(getFileInfo.value.orderFileId)
  connectList.value = data.result
}
const loadExcel = () => {
  LuckyExcel.transformExcelToLuckyByUrl(
    '/api/sys/static/' + getFileInfo.value.mergeFilePath,
    new Date().getTime() + '.xlsx',
    async (exportJson: any) => {
      console.log('---exportJson', exportJson)
      initIsSetSheetMark(exportJson.sheets.length)
      initExcelAreaMarksKey(exportJson.sheets.length)

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

      setSheetAuthority(exportJson)
      isFunction((window as any)?.luckysheet?.destroy) && luckysheet.destroy()
      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: (index: any) => {
            const sheet = luckysheet.getSheet({ index })
            nextTick(() => setSheetAreaMark(sheet))
          },
          workbookCreateAfter: () => {
            const sheet = luckysheet.getSheet()
            nextTick(() => setSheetAreaMark(sheet))
          }
        }
      })
    }
  )
}

const setSheetAreaMark = (sheet: any) => {
  if (!!isSetSheetMark.value[sheet.order]) {
    return
  }
  // 修改当前sheet 已经标记
  isSetSheetMark.value[sheet.order] = true
  // 判断本地是否记有第一个sheet页的标
  if (locaExcelAreaMarks[sheet.order].length) {
    locaExcelAreaMarks[sheet.order].forEach((item: any) => {
      // 设置数据区标记
      luckysheet.menuButton.customUpdateFormat(
        null,
        'bg',
        areaMarksColor['data'],
        item.beginRow,
        item.endRow,
        item.beginColum,
        item.endColum,
        false
      )
      if (item.excelAreaTitle.length) {
        const areas = JSON.parse(item.titleArea)
        areas?.forEach((area: any) => {
          luckysheet.menuButton.customUpdateFormat(
            null,
            'bg',
            areaMarksColor['head'],
            area.sr,
            area.er,
            area.sc,
            area.ec,
            false
          )
        })
      }
      if (item.desGroups.length) {
        item?.desGroups.forEach((area) => {
          if (area.beginRow !== null && area.beginRow !== '') {
            luckysheet.menuButton.customUpdateFormat(
              null,
              'bg',
              areaMarksColor['attch'],
              area.beginRow,
              area.endRow,
              area.beginColum,
              area.endColum,
              false
            )
          }

          if (area.groupTitles.length) {
            area.groupTitles.forEach((a) => {
              luckysheet.menuButton.customUpdateFormat(
                null,
                'bg',
                areaMarksColor['attch_head'],
                a.row,
                a.row,
                a.colum,
                a.colum,
                false
              )
            })
          }

          if (area.areaTitles.length) {
            area.areaTitles.forEach((a) => {
              luckysheet.menuButton.customUpdateFormat(
                null,
                'bg',
                areaMarksColor['attch_title'],
                a.row,
                a.row,
                a.colum,
                a.colum,
                false
              )
            })
          }
        })
      }
    })
  }
}

const queryDict = async (code: string) => {
  const { data } = await apiDictList({
    dictCodes: code
  })
  areaTypeSelectOption.value = data.result[code]
}
const getAreaTypeText = (value: string) => {
  const item = areaTypeSelectOption.value.find((v) => v.value == value)
  return item?.label || '--'
}

const runResultData = ref([])
const runResultTitle = ref([])
const runResultVisible = ref(false)
const toRun = async () => {
  const loadingInstance = ElLoading.service({
    fullscreen: true,
    text: '解析中...'
  })
  try {
    const { data } = await excelMarkRun(getFileInfo.value.orderFileId)
    nextTick(() => {
      // Loading should be closed asynchronously
      loadingInstance.close()
    })
    if (data?.code != 200) {
      ElMessage.error(data?.message || '操作失败！')
      return
    }

    if (!data.result.length) return

    data.result.forEach((item) => {
      item.expendData = {}
      for (const key in item) {
        if (typeof item[key] == 'object') {
          item.expendData[key] = item[key]
          delete item[key]
        }
      }
    })

    runResultData.value = data.result
    runResultTitle.value = Object.keys(data.result[0]).filter((field) => {
      return field != 'sortNum' && field != '数据区' && field != 'expendData'
    })
    // const idx = runResultTitle.value.findIndex((v) => v == 'sortNum')
    // runResultTitle.value.splice(idx, 1)
    runResultVisible.value = true
  } catch {
    nextTick(() => {
      // Loading should be closed asynchronously
      loadingInstance.close()
    })
  }
}
onMounted(() => {
  loadExcel()
  queryConnectList()
  queryDict('excel_area_type')
})
onUnmounted(() => {
  isFunction((window as any)?.luckysheet?.destroy) && luckysheet.destroy()
})
</script>
<style lang="scss" scoped>
.comment-form {
  .el-form-item--small {
    margin-bottom: 15px;
  }
}
</style>
<style lang="scss">
.current-area-mark {
  .el-descriptions__label {
    width: 8em;
  }
}
</style>
