<template>
    <hc-drawer
        v-model="isShow"
        ui="hc-project-list-edit-element-drawer"
        to-id="hc-layout-box"
        is-close
        @close="drawerClose"
    >
        <hc-page-split :fold="false" :options="splitOptions">
            <template #left>
                <hc-card
                    :title="`【编辑元素】${
                        type == 2 ? dataInfo.title : dataInfo.tableName
                    }`"
                    :loading="tableFormLoading"
                >
                    <template #search>
                        <div class="text-13px color-#f0720a">
                            <span>提示：鼠标右键功能：更换匹配元素字段、新增元素字段、删除匹配元素字段、公式配置</span>
                            <span class="ml-14px text-red-6">红色：代表匹配不成功、</span>
                            <span class="text-blue-6">蓝色代表推荐匹配元素字段、</span>
                            <span class="text-green-6">绿色代表匹配成功</span>
                        </div>
                    </template>
                    <hc-table-form
                        ref="excelRef"
                        :html="excelHtml"
                        is-warn
                        @tap="excelClick"
                    />
                </hc-card>
            </template>
            <hc-card scrollbar>
                <template #header>
                    <el-button type="warning" @click="formAdjustmentsClick">
                        表单调整
                    </el-button>
                    <el-button type="primary" @click="formulaConfigClick">
                        公式配置
                    </el-button>
                </template>
                <template #extra>
                    <el-button @click="drawerClose">返回上一级</el-button>
                </template>
                <el-form
                    ref="formRef"
                    :model="formModel"
                    :rules="formRules"
                    label-position="left"
                    label-width="auto"
                >
                    <el-form-item label="当前元素坐标：" prop="colName">
                        <el-input
                            v-model="formModel.colName"
                            placeholder="请点击左侧表单"
                            disabled
                        />
                    </el-form-item>
                    <el-form-item label="将元素替换为：" prop="htmlType">
                        <el-select
                            v-model="formModel.htmlType"
                            filterable
                            block
                            placeholder="输入元素名称搜索"
                            @change="allElementChange"
                        >
                            <template v-for="item in allElement" :key="item.id">
                                <el-option
                                    :label="item.eName"
                                    :value="item.id"
                                />
                            </template>
                        </el-select>
                    </el-form-item>
                </el-form>
                <div class="action-btn-box mb-40px mt-10px text-center">
                    <el-button
                        type="primary"
                        :loading="submitLoading"
                        @click="savingClick"
                    >
                        临时保存
                    </el-button>
                    <el-button
                        type="danger"
                        style="margin-left: 50px"
                        :loading="submitLoading"
                        @click="delElement"
                    >
                        删除元素
                    </el-button>
                </div>
                <div class="hc-edit-element-collapse">
                    <el-collapse v-model="activeNames">
                        <el-collapse-item name="key1">
                            <template #title>
                                <div class="hc-collapse-item-header hc-flex">
                                    <div class="title text-green">
                                        本次临时保存的元素
                                    </div>
                                    <div class="hc-extra-text-box">
                                        <el-button
                                            type="success"
                                            size="small"
                                            :loading="submitLoading"
                                            @click.stop="dialogSubmit"
                                        >
                                            全部提交保存
                                        </el-button>
                                    </div>
                                </div>
                            </template>
                            <hc-table
                                ref="formArrRef"
                                :column="tableColumn"
                                :is-index="false"
                                :datas="formDataArr"
                            >
                                <template #action="{ index }">
                                    <el-link
                                        v-loading="submitLoading"
                                        type="danger"
                                        @click="rowDelClick(index)"
                                    >
                                        删除
                                    </el-link>
                                </template>
                            </hc-table>
                        </el-collapse-item>
                        <el-collapse-item name="key2">
                            <template #title>
                                <div class="hc-collapse-item-header hc-flex">
                                    <div class="title text-orange">
                                        未进行匹配的元素字段
                                    </div>
                                    <div class="hc-extra-text-box">
                                        <el-button
                                            type="warning"
                                            size="small"
                                            :loading="submitLoading"
                                            @click.stop="addElementClick"
                                        >
                                            新增元素
                                        </el-button>
                                    </div>
                                </div>
                            </template>
                            <div class="hc-collapse-item-button">
                                <template
                                    v-for="item in matchElement"
                                    :key="item.id"
                                >
                                    <el-button
                                        type="warning"
                                        size="small"
                                        plain
                                        @click="matchElementClick(item)"
                                    >
                                        {{ item.eName }}
                                    </el-button>
                                </template>
                                <hc-empty v-if="matchElement.length <= 0" />
                            </div>
                        </el-collapse-item>
                    </el-collapse>
                </div>
            </hc-card>

            <!-- 添加新的元素字段 -->
            <hc-dialog
                v-model="isAddElementShow"
                ui="hc-project-list-edit-element-add-element"
                widths="50rem"
                is-table
                title="添加新的元素字段"
                :padding="false"
                @close="addElementClose"
            >
                <template #extra>
                    <el-button
                        type="danger"
                        size="small"
                        @click="addElementData"
                    >
                        新增元素
                    </el-button>
                </template>
                <hc-table
                    :column="addElementColumn"
                    :datas="addElementTable"
                    :is-current-row="false"
                >
                    <template #eName="{ row }">
                        <hc-table-input v-model="row.eName" type="text" />
                    </template>
                    <template #eType="{ row }">
                        <el-select v-model="row.eType" filterable block>
                            <template v-for="item in dataType" :key="item.id">
                                <el-option
                                    :label="item.label"
                                    :value="item.value"
                                />
                            </template>
                        </el-select>
                    </template>
                    <template #action="{ index }">
                        <el-link
                            type="danger"
                            @click="addElementDelClick(index)"
                        >
                            删除
                        </el-link>
                    </template>
                </hc-table>
                <template #footer>
                    <el-button hc-btn @click="addElementClose">取消</el-button>
                    <el-button
                        hc-btn
                        type="primary"
                        :loading="addElementLoading"
                        @click="addElementSubmit"
                    >
                        确定
                    </el-button>
                </template>
            </hc-dialog>
        </hc-page-split>
    </hc-drawer>
</template>

<script setup>
import { ref, watch } from 'vue'
import {
    arrIndex,
    deepClone,
    formValidate,
    getArrValue,
    getObjValue,
    isNullES,
} from 'js-fast-way'
import { getDictionaryData } from '~uti/tools'
import excelApi from '~api/exctab/exceltab'
import { useAppStore } from '~src/store'
const props = defineProps({
    info: {
        type: Object,
        default: () => ({}),
    },
    data: {
        type: Object,
        default: () => ({}),
    },
    type: {
        type: [String, Number],
        default: '', //默认没有，独立表单库类型为2
    },
})
//事件
const emit = defineEmits(['close', 'toPage'])
const store = useAppStore()
//双向绑定
const isShow = defineModel('modelValue', {
    default: false,
})

//监听数据
const dataInfo = ref(props.info)
const editData = ref(props.data)
const type = ref(props.type)
watch(
    () => [props.info, props.data, props.type],
    ([info, data, tpe]) => {
        dataInfo.value = getObjValue(info)
        editData.value = getObjValue(data)
        type.value = tpe
    },
    { immediate: true, deep: true },
)

//监听显示
watch(isShow, (val) => {
    if (val) getDataApi()
    store.setIsShowName(true)
})

//页面分割
const splitOptions = { sizes: [70, 30], snapOffset: 0, minSize: [300, 300] }

//处理相关数据
const excelRef = ref(null)
const excelHtml = ref('')
const tableFormLoading = ref(true)
const getDataApi = async () => {
    const { pkeyId, excelId, primaryKeyId, excelIds } = getObjValue(
        dataInfo.value,
    )
    if (type.value !== 2) {
        if (isNullES(pkeyId) || isNullES(excelId)) {
            tableFormLoading.value = false
            window?.$message.warning('表单值异常，请联系管理员')
            return
        }
    } else {
        if (isNullES(primaryKeyId) || isNullES(excelIds)) {
            tableFormLoading.value = false
            window?.$message.warning('表单值异常，请联系管理员')
            return
        }
    }

    tableFormLoading.value = true
    const { data } = await excelApi.getExcelHtml({
        pkeyId: pkeyId ? pkeyId : primaryKeyId, //独立表单库取primaryKeyId
    })
    excelHtml.value = data || ''
    await getElementInfoByTabId()
    await getUnMatchField()
    getDataType().then()
    tableFormLoading.value = false
}

//获取全部元素
const allElement = ref([])
const getElementInfoByTabId = async () => {
    const { initTableId } = getObjValue(dataInfo.value)
    const { data } = await excelApi.getElementInfoByTabId({
        tabId: initTableId,
    })
    allElement.value = getArrValue(data)
}
const allElementChange = () => {
    const { htmlType } = formModel.value
    let info = getObjValue(
        allElement.value.find((item) => item.id === htmlType),
    )
    formModel.value.htmlName = info.eName
}

//提取未匹配的元素字段
const matchElement = ref([])
const getUnMatchField = async () => {
    const { pkeyId, initTableId, primaryKeyId } = getObjValue(dataInfo.value)
    const { data } = await excelApi.getUnMatchField({
        pkeyId: pkeyId ? pkeyId : primaryKeyId,
        tabId: initTableId,
    })
    matchElement.value = getArrValue(data)
}

//未匹配的元素
const matchElementClick = ({ id, eName }) => {
    if (submitLoading.value) return
    formModel.value.htmlType = id
    formModel.value.htmlName = eName
}

//元素数据类型
const dataType = ref([])
const getDataType = async () => {
    dataType.value = await getDictionaryData('data_type')
}

//基础表单
const formRef = ref(null)
const formModel = ref({})
const formRules = {
    colName: { required: true, trigger: 'blur', message: '请先获取元素坐标' },
    htmlType: {
        required: true,
        trigger: 'blur',
        message: '请先寻找将元素替换为',
    },
}

//元素被点击
const excelClick = async (item) => {
    const { pkeyId, primaryKeyId } = getObjValue(dataInfo.value)
    if (isNullES(pkeyId) && isNullES(primaryKeyId)) {
        window?.$message.warning('表单值异常，请联系管理员')
        return
    }
    const data = await getDomAttribute(item)
    const arr = getArrValue(formDataArr.value)
    const index = arrIndex(arr, 'key', data.key)
    // const colName = data.name || data.text || data.key
    const colName = data.text 
    const htmlType = index !== -1 ? arr[index].htmlType : ''
    const htmlName = index !== -1 ? arr[index].htmlName : ''
    const type = index !== -1 ? arr[index].type : ''
    formModel.value = {
        tabId: pkeyId ? pkeyId : primaryKeyId,
        colName: colName,
        key: data.key,
        tdIndex: data.td,
        trIndex: data.tr,
        htmlType: htmlType,
        htmlName: htmlName,
        type: type,
    }
}

//获取元素相关信息
const keys = [
    'type',
    'key',
    'tr',
    'td',
    'index',
    'x1',
    'y1',
    'x2',
    'y2',
    'name',
    'text',
    'rows',
    'format',
    'tip',
    'weighing',
    'label',
    'value',
    'src',
    'val',
    'contractid',
    'pkeyid',
    'objs',
    'range',
    'def',
    'max',
]
const getDomAttribute = async (item) => {
    const dom = item?.target
    let obj = { zdom: item }
    for (let i = 0; i < keys.length; i++) {
        obj[keys[i]] = await getAttribute(dom, keys[i])
    }
    return obj
}

//获取属性
const getAttribute = async (dom, key) => {
    try {
        return dom?.getAttribute(`data-${key}`)
    } catch (e) {
        return null
    }
}

//临时保存表格
const formArrRef = ref(null)
const tableColumn = [
    { key: 'colName', name: '当前元素', minWidth: 120 },
    { key: 'key', name: '元素位置', minWidth: 120 },
    { key: 'htmlName', name: '匹配元素', minWidth: 120 },
    { key: 'tdIndex', name: 'td(坐标)', align: 'center', width: 60 },
    { key: 'trIndex', name: 'tr(坐标)', align: 'center', width: 60 },
    { key: 'action', name: '操作', align: 'center', width: 70, fixed: 'right' },
]

//临时保存
const formDataArr = ref([])
const savingClick = async () => {
    const res = await formValidate(formRef.value)
    if (!res) return
    const form = deepClone(formModel.value)
    const arr = formDataArr.value
    const index = arrIndex(arr, 'key', form.key)
    const obj = { ...form, type: '' }
    if (index !== -1) {
        arr[index] = obj
    } else {
        arr.push(obj)
    }
    formModel.value = {}
    window?.$message.success('临时保存成功，记得点击下方的全部提交保存')
}

//删除元素
const delElement = () => {
    const form = deepClone(formModel.value)
    if (isNullES(form.tdIndex) || isNullES(form.trIndex)) {
        window?.$message.warning('请先在左侧表单，点击要删除的元素')
        return
    }
    const arr = formDataArr.value
    const index = arrIndex(arr, 'key', form.key)
    const obj = {
        ...form,
        htmlType: null,
        htmlName: '删除元素',
        type: 'del',
    }
    if (index !== -1) {
        arr[index] = obj
    } else {
        arr.push(obj)
    }
    formModel.value = {}
    window?.$message.success('当前操作临时保存，记得点击下方的全部提交保存')
}

//删除临时保存
const rowDelClick = (index) => {
    formDataArr.value.splice(index, 1)
}

//折叠面板
const activeNames = ref(['key2'])

//保存数据
const submitLoading = ref(false)
const dialogSubmit = async () => {
    const arr = deepClone(formDataArr.value)
    if (arr.length <= 0) {
        window?.$message.warning('请先添加要操作的元素')
        return
    }
    //数据分类
    submitLoading.value = true
    let matchArr = [],
        delArr = []
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].type === 'del') {
            delArr.push({
                ...arr[i],
                colName: '/',
                htmlName: null,
                type: null,
            })
        } else {
            matchArr.push({
                ...arr[i],
                colName: '',
                htmlName: null,
                type: null,
            })
        }
    }
    await matchElementApi(matchArr)
    await delElementApi(delArr)
    window?.$message.success('操作完成')
    clearFormData()
    await getDataApi()
    submitLoading.value = false
}

//匹配元素
const matchElementApi = async (data) => {
    if (data.length <= 0) return
    await excelApi.saveTabColInfo(data)
}

//删除元素
const delElementApi = async (arr, batchSize = 3) => {
    if (arr.length <= 0) return
    const totalBatches = Math.ceil(arr.length / batchSize)
    let totalSuccess = 0,
        totalFail = 0
    for (let i = 0; i < arr.length; i += batchSize) {
        const batch = arr.slice(i, i + batchSize)
        const currentBatch = Math.floor(i / batchSize) + 1
        console.log(`正在处理第 ${currentBatch}/${totalBatches} 批`)

        const results = await Promise.all(
            batch.map(async (element) => {
                try {
                    await excelApi.delExcelElement(element)
                    return { element, success: true }
                } catch (error) {
                    console.error(`删除元素 ${element} 时发生错误:`, error)
                    return { element, success: false, error }
                }
            }),
        )
        const batchSuccess = results.filter((r) => r.success).length
        const batchFail = results.filter((r) => !r.success).length
        totalSuccess += batchSuccess
        totalFail += batchFail

        console.log(
            `第 ${currentBatch} 批处理结果: 成功 ${batchSuccess}, 失败 ${batchFail}`,
        )
    }
    console.log(`总计处理结果: 成功 ${totalSuccess}, 失败 ${totalFail}`)
}

//新增元素
const isAddElementShow = ref(false)
const addElementClick = () => {
    addElementTable.value = [{ eName: '', eType: null }]
    addElementLoading.value = false
    isAddElementShow.value = true
}

//表格数据
const addElementColumn = [
    { key: 'eName', name: '清表元素名称' },
    { key: 'eType', name: '元素数据类型' },
    { key: 'action', name: '操作', align: 'center', width: 70, fixed: 'right' },
]
const addElementTable = ref([])

//新增数据
const addElementData = () => {
    addElementTable.value.push({ eName: '', eType: null })
}

//删除
const addElementDelClick = (index) => {
    addElementTable.value.splice(index, 1)
}

//提交新增
const addElementLoading = ref(false)
const addElementSubmit = async () => {
    const arr = addElementTable.value
    if (arr.length <= 0) {
        window?.$message.warning('请先添加元素字段')
        return
    }
    const isValid = arr.every((val) => val.eName && val.eType)
    if (!isValid) {
        window?.$message.warning('请先完善数据')
        return
    }
    const { pid } = getObjValue(editData.value)
    const { pkeyId, initTableName, primaryKeyId } = getObjValue(dataInfo.value)
    const { isRes } = await excelApi.submitBatch({
        projectId: pid,
        initTableName,
        id: pkeyId ? pkeyId : primaryKeyId,
        listData: arr,
    })
    if (!isRes) return
    window?.$message.success('操作完成')
    addElementClose()
    await getElementInfoByTabId()
    await getUnMatchField()
}

//关闭新增元素
const addElementClose = () => {
    isAddElementShow.value = false
    addElementLoading.value = false
    addElementTable.value = []
}

//表单调整
const formAdjustmentsClick = () => {
    drawerClose()
    emit('toPage', 'adjustment')
}

//公式配置
const formulaConfigClick = () => {
    drawerClose()
    emit('toPage', 'formula')
}

//清空数据
const clearFormData = () => {
    formModel.value = {}
    formDataArr.value = []
}

//关闭抽屉
const drawerClose = () => {
    isShow.value = false
    clearFormData()
    emit('close')
}
</script>

<style lang="scss">
.el-overlay .el-drawer.hc-project-list-edit-element-drawer {
    background-color: #f1f5f8;
    .hc-table-form-data-item {
        padding: 0;
    }
    .hc-table-form-data-item .hc-excel-table-form {
        background: #e4e7eb;
    }
    .hc-edit-element-collapse {
        position: relative;
        border: 1px solid #ebeef5;
        border-top: 0;
        border-bottom: 0;
        .el-collapse {
            --el-collapse-header-bg-color: #f9f9f9;
        }
        .el-collapse .el-collapse-item {
            .el-collapse-item__header {
                padding-left: 10px;
            }
            .el-collapse-item__wrap {
                padding: 10px;
                border-top: 1px solid #ebeef5;
                .el-collapse-item__content {
                    padding-bottom: 0;
                }
            }
        }
        .el-collapse .el-collapse-item .hc-collapse-item-header {
            position: relative;
            flex: 1;
            .title {
                position: relative;
                flex: 1;
                text-align: left;
            }
            .hc-extra-text-box {
                position: relative;
                margin-right: 24px;
            }
        }
    }
    .hc-collapse-item-button {
        position: relative;
        .el-button {
            margin-right: 10px;
            margin-bottom: 5px;
        }
        .el-button + .el-button {
            margin-left: 0;
        }
    }
}
.el-overlay-dialog
    .el-dialog.hc-new-dialog.hc-project-list-edit-element-add-element {
    height: calc(100% - 300px);
    --el-dialog-margin-top: 150px;
}
</style>
