<template>
  <el-form
    size="small"
    ref="form"
    class="set-area-form"
    :model="formState"
    :rules="rules"
    label-width="6em"
  >
    <el-row :gutter="10">
      <el-col :span="24">
        <el-form-item label="标记区域">
          <el-tag>
            {{
              getRangetxt(
                formState.beginRow,
                formState.endRow,
                formState.beginColum,
                formState.endColum
              )
            }}
          </el-tag>
        </el-form-item>
      </el-col>
      <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="7em">
          <el-checkbox true-label="Y" false-label="N" v-model="formState.checkSelf">是</el-checkbox>
        </el-form-item>
      </el-col> -->
      <el-col :span="24">
        <p class="table-title">数据说明区</p>
        <vxe-table
          border
          size="mini"
          max-height="200"
          :data="captionArea"
          :edit-config="{ trigger: 'click', mode: 'cell' }"
          :row-config="{ isCurrent: true }"
        >
          <vxe-column title="单元格值" field="title" :edit-render="{}">
            <template #default="{ row }">{{ row.title }}</template>
            <template #edit="{ row }">
              <el-input size="small" v-model="row.title"></el-input>
            </template>
          </vxe-column>
          <vxe-column title="单元格" width="90">
            <template #default="{ row }">{{
              getRangetxt(row.row, row.row, row.colum, row.colum)
            }}</template>
          </vxe-column>
          <vxe-column title="操作" width="50">
            <template #default="{ row, $rowIndex }">
              <el-link
                type="danger"
                style="font-size: 12px"
                @click="delCaptionAndExclude(row, $rowIndex, 1)"
                >删除</el-link
              >
            </template>
          </vxe-column>
        </vxe-table>

        <p class="table-title mt-2">排除区</p>
        <vxe-table
          border
          size="mini"
          max-height="200"
          :data="excludeArea"
          :edit-config="{ trigger: 'click', mode: 'cell' }"
          :row-config="{ isCurrent: true }"
        >
          <vxe-column title="单元格值" field="title" :edit-render="{}">
            <template #default="{ row }">{{ row.title }}</template>
            <template #edit="{ row }">
              <el-input size="small" v-model="row.title"></el-input>
            </template>
          </vxe-column>
          <vxe-column title="单元格" width="90">
            <template #default="{ row }">{{
              getRangetxt(row.row, row.row, row.colum, row.colum)
            }}</template>
          </vxe-column>
          <vxe-column title="操作" width="50">
            <template #default="{ row, $rowIndex }">
              <el-link
                type="danger"
                style="font-size: 12px"
                @click="delCaptionAndExclude(row, $rowIndex, 2)"
                >删除</el-link
              >
            </template>
          </vxe-column>
        </vxe-table>

        <p class="table-title mt-2">结束标识</p>
        <vxe-table
          border
          size="mini"
          max-height="200"
          :data="endArea"
          :edit-config="{ trigger: 'click', mode: 'cell' }"
          :row-config="{ isCurrent: true }"
        >
          <vxe-column title="单元格值" field="title" :edit-render="{}">
            <template #default="{ row }">{{ row.title }}</template>
            <template #edit="{ row }">
              <el-input size="small" v-model="row.title"></el-input>
            </template>
          </vxe-column>
          <vxe-column title="单元格" width="90">
            <template #default="{ row }">{{
              getRangetxt(row.row, row.row, row.colum, row.colum)
            }}</template>
          </vxe-column>
          <vxe-column title="操作" width="50">
            <template #default="{ row, $rowIndex }">
              <el-link
                type="danger"
                style="font-size: 12px"
                @click="delCaptionAndExclude(row, $rowIndex, 3)"
                >删除</el-link
              >
            </template>
          </vxe-column>
        </vxe-table>
      </el-col>
      <el-col style="margin-top: 10px">
        <el-form-item label-width="0">
          <el-button-group>
            <el-button type="primary" @click="setAreaMark('data')">标记数据区</el-button>
            <el-button type="primary" @click="setCaptionArea">标记说明区</el-button>
            <el-button type="primary" @click="setExcludeArea">标记排除区</el-button>
            <el-button type="primary" @click="setEndArea">标记结束区</el-button>
            <el-button type="success" @click="nextStep">下一步</el-button>
          </el-button-group>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script lang="ts" setup>
import { apiDictList } from '@/api/common'
import { areaMarksColor } from '@/constants/excelConfig'
import type { Recordable } from '@/types/global'
import { getRangePosition, getRangetxt, handleRangeCell, setRangeBackground } from '@/utils/excel'
import { ElMessage, type FormInstance } from 'element-plus'
import { onMounted, reactive, ref, unref, watch } from 'vue'

const props = defineProps(['areaTypeLen'])

const luckysheet = (window as any).luckysheet
const emits = defineEmits(['next'])
const areaTypeSelectOption = ref<Recordable>([])
const formState = reactive<Recordable>({
  excelAreaNicname: '',
  excelAreaType: '',
  checkNumber: 1,
  oneself: 'N',
  checkSelf: 'N',
  sheetNum: 0,
  beginRow: '',
  beginColum: '',
  endRow: '',
  endColum: ''
})

watch(
  () => formState.excelAreaType,
  (val) => {
    if (val) {
      formState.excelAreaNicname =
        areaTypeSelectOption.value.find((v: any) => v.value == val).label +
        (props.areaTypeLen[val] || '')
    }
  }
)

const tableData = ref([])
const form = ref<FormInstance>()
const rules = reactive({
  excelAreaNicname: [{ required: true, message: '请输入区域别称！', trigger: 'change' }],
  excelAreaType: [{ required: true, message: '请选择区域类型！', trigger: 'change' }],
  checkNumber: [
    {
      validator: (rule: any, value: any, cb: Function) => {
        if (value <= 0) {
          cb(new Error('请输入正整数！'))
          return false
        }
        return true
      },
      trigger: 'change'
    }
  ]
})
const resetFormState = () => {
  // 重置字段
  form.value?.resetFields(['excelAreaNicname', 'excelAreaType', 'checkNumber', 'oneself'])
  // 清空位置信息
  Object.assign(formState, {
    sheetNum: 0,
    beginRow: '',
    beginColum: '',
    endRow: '',
    endColum: ''
  })

  excludeArea.value = []
  captionArea.value = []
  endArea.value = []
}

const setAreaMark = (type: 'data') => {
  const position = getRangePosition()
  if (!position) return
  // 清除已经设置过的数据区颜色
  if (formState.beginColum !== '') {
    luckysheet.menuButton.customUpdateFormat(
      null,
      'bg',
      areaMarksColor['default'],
      formState.beginRow,
      formState.endRow,
      formState.beginColum,
      formState.endColum,
      false
    )
  }
  // 设置目前标记区域颜色
  luckysheet.setRangeFormat('bg', areaMarksColor[type])

  Object.assign(formState, position)
}

const captionArea = ref<Recordable[]>([])
const excludeArea = ref<Recordable[]>([])
const endArea = ref<Recordable[]>([])
// 设置说明区
const setCaptionArea = () => {
  const cells = getRangeCellValue('caption')

  // 去除重复单元格
  captionArea.value.push(
    ...cells.filter(
      (cell) => captionArea.value.findIndex((v) => v.row == cell.row && v.colum == cell.colum) == -1
    )
  )
}
// 设置排除区
const setExcludeArea = () => {
  const cells = getRangeCellValue('exclude')

  // 去除重复单元格
  excludeArea.value.push(
    ...cells.filter(
      (cell) => excludeArea.value.findIndex((v) => v.row == cell.row && v.colum == cell.colum) == -1
    )
  )
}

const setEndArea = () => {
  const cells = getRangeCellValue('end')

  // 去除重复单元格
  endArea.value.push(
    ...cells.filter(
      (cell) => endArea.value.findIndex((v) => v.row == cell.row && v.colum == cell.colum) == -1
    )
  )
}

const delCaptionAndExclude = (row: any, index: number, type = 1) => {
  ;(type == 1 ? captionArea : type == 2 ? excludeArea : endArea).value.splice(index, 1)
  setRangeBackground(row, areaMarksColor[type == 1 ? 'default' : 'data'])
}
// 获取有值的单元格
const getRangeCellValue = (type: 'caption' | 'exclude' | 'end') => {
  return handleRangeCell(luckysheet.getRangeValue(), (c: any) => {
    luckysheet.menuButton.customUpdateFormat(
      null,
      'bg',
      areaMarksColor[type],
      c.row,
      c.row,
      c.colum,
      c.colum,
      false
    )
  }, false)
}

const queryDict = async (code: string) => {
  const { data } = await apiDictList({
    dictCodes: code
  })
  areaTypeSelectOption.value = data.result[code]
}

const nextStep = async () => {
  // 验证是否有标记数据区
  if (formState.beginRow === '') {
    return ElMessage.error('请标记数据区！')
  }
  // 验证表单
  await form.value?.validateField(['excelAreaNicname', 'excelAreaType'])

  // 下一步去设置标题
  emits('next', 1, {
    ...formState,
    excludeTitles: unref(excludeArea),
    dataTitles: unref(captionArea),
    endTitles: unref(endArea)
  })
}

onMounted(() => {
  queryDict('excel_area_type')
})

// 暴露方法
defineExpose({
  resetFormState
})
</script>
<style lang="scss" scoped>
.set-area-form {
  padding: 6px;
}
.table-title {
  font-size: 14px;
}
</style>
