<template>
    <hc-drawer v-model="isShow" ui="hc-project-list-edit-formula-drawer" to-id="hc-layout-box" is-close @close="drawerClose">
        <hc-card is-action-btn :title="cardFormulaTitle" :scrollbar="isScrollBar">
            <div class="hc-project-list-edit-formula-card" :class="isScrollBar ? '' : 'is-no-scroll'">
                <!-- 顶部操作 -->
                <div class="hc-formula-card-box border-dashed-card hc-flex mb-14px h-58px">
                    <div class="retain hc-flex h-full w-174px">
                        <el-checkbox v-model="isRetain" size="large" />
                        <span class="ml-5px text-14px">保留</span>
                        <div class="relative ml-5px w-90px">
                            <el-input-number v-model="retainNum" block :step="1" :min="0" :max="5" :disabled="!isRetain" controls-position="right" />
                        </div>
                        <span class="ml-5px text-14px">位</span>
                    </div>
                    <div class="range hc-flex h-full w-155px">
                        <el-button :type="formulaCardType === 'range' ? 'primary' : ''" @click="setDeviationRange">允许偏差值范围</el-button>
                    </div>
                    <div class="menu h-full flex-1">
                        <hc-body padding="0">
                            <el-menu :default-active="formulaMenuIndex" mode="horizontal" @select="handleFormulaMenu">
                                <el-sub-menu v-for="(arr, key, index) in formulaMenuList" :key="key" :index="key">
                                    <template #title>{{ key }}</template>
                                    <el-menu-item v-for="(item, i) in arr" :key="i" :index="`${index + 1}-${i + 1}`">{{ item?.name }}</el-menu-item>
                                </el-sub-menu>
                            </el-menu>
                        </hc-body>
                    </div>
                    <div class="hand hc-flex h-full w-100px">
                        <el-button @click="handWritClick">手写模式</el-button>
                    </div>
                </div>
                <!-- 函数公式 -->
                <div class="border-dashed-card hc-formula-card-math mb-14px">
                    <div class="header hc-flex">
                        <div class="name flex-1 text-14px">函数公式.</div>
                        <div class="extra relative ml-24px">
                            <el-button size="small" @click="clearResetFunClick">清除选择</el-button>
                            <el-button :type="formulaCardType === 'reset-fun' ? 'primary' : 'info'" size="small" @click="resetFunClick">重置函数</el-button>
                        </div>
                    </div>
                    <div class="body relative">
                        <template v-for="(item, index) in resultFormula" :key="index">
                            <span class="element-class text-22px" :class="item.selected ? 'is-cur' : ''" @click="resultFormulaItem(item, index)">{{ item.name }}</span>
                        </template>
                        <span class="ml-10px mr-10px text-24px">=</span>
                        <template v-for="(item, index) in processFormula" :key="index">
                            <el-tooltip :content="item.tableName" placement="top-start" :disabled="item.type !== 'Element' || isNullES(item.tableName)">
                                <span class="element-class text-22px" :class="item.selected ? 'is-cur' : ''" :data-name="getItemTableName(item)" @click="processFormulaItem(item, index)">{{ item.name }}</span>
                            </el-tooltip>
                        </template>
                    </div>
                </div>
                <!-- 重置函数 -->
                <div v-if="formulaCardType === 'reset-fun'" class="hc-formula-reset-fun mb-14px">
                    <hc-body split padding="0">
                        <template #left>
                            <hc-card class="reset-fun-left-card" scrollbar :loading="treeResetFunLoading">
                                <template #header>
                                    <hc-search-input v-model="resetFunTree" @search="resetFunTreeSearch" />
                                </template>
                                <el-tree
                                    v-if="isResetFunTreeLazy" ref="treeResetFunLazyRef" :default-expanded-keys="treeResetFunLazyExpanded" node-key="id" :props="defaultProps"
                                    :expand-on-click-node="false" lazy highlight-current :load="treeResetFunLazyLoad" @node-click="treeResetFunLazyClick"
                                />
                                <el-tree
                                    v-else ref="treeResetFunAllRef" :data="resetFunTreeAll" :props="defaultProps" node-key="id"
                                    :expand-on-click-node="false" @node-click="treeResetFunLazyClick"
                                />
                            </hc-card>
                        </template>
                        <hc-card class="reset-fun-right-card">
                            <template #header>
                                <hc-search-input v-model="resetFunEle" placeholder="请输入你想搜索的元素字段" @search="resetFunEleSearch" />
                            </template>
                            <div class="body h-full">
                                <div v-loading="isResetFunEleLoading" class="tag-box">
                                    <template v-for="(item, index) in resetFunEleData" :key="index">
                                        <el-button v-if="item.k" type="primary" plain size="small" @click="resetFunEleTagClick(item)">{{ item.name }}</el-button>
                                        <el-button v-else type="primary" plain size="small" @click="resetFunEleTagClick(item)">{{ item.eName }}</el-button>
                                    </template>
                                </div>
                                <div class="action-box hc-flex">
                                    <div class="left hc-flex flex-1">
                                        <div class="btn hc-flex-center" @click="resetFunText">
                                            <span class="text">输入值</span>
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunBrackets('(')">
                                            <span class="symbol">(</span>
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunBrackets(')')">
                                            <span class="symbol">)</span>
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunOperator('+')">
                                            <i class="i-ri-add-line" />
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunOperator('-')">
                                            <i class="i-ri-subtract-line" />
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunOperator('*')">
                                            <i class="i-ri-close-line" />
                                        </div>
                                        <div class="btn hc-flex-center" @click="resetFunOperator('%')">
                                            <hc-icon name="divide" />
                                        </div>
                                    </div>
                                    <div class="right hc-flex">
                                        <el-tooltip content="删除元素" placement="top-end">
                                            <div class="btn hc-flex-center" @click="resetFunDel">
                                                <i class="i-ri-delete-back-2-line" />
                                            </div>
                                        </el-tooltip>
                                        <el-tooltip content="清空所有" placement="top-end">
                                            <div class="btn hc-flex-center" @click="resetFunClear">
                                                <i class="i-ri-delete-bin-3-line" />
                                            </div>
                                        </el-tooltip>
                                    </div>
                                </div>
                                <div class="input-box">
                                    <draggable v-model="selectEleFormula" item-key="index">
                                        <template #item="{ element }">
                                            <span class="element-class" :class="[`is-${element.type}`, element.selected ? 'is-cur' : '']" @click="selectEleFormulaItem(element)">{{ element.name }}</span>
                                        </template>
                                    </draggable>
                                </div>
                            </div>
                        </hc-card>
                    </hc-body>
                </div>
                <!-- 函数公式运算执行溯源 -->
                <div v-if="formulaCardType === 'project'" class="border-dashed-card hc-formula-card-project mb-14px">
                    <div class="header mb-14px text-14px">函数公式运算执行溯源</div>
                    <div class="body relative">
                        <el-select v-model="projectId" filterable clearable class="mr-14px w-380px" placeholder="选择项目" @change="projectChange">
                            <el-option v-for="item in projectList" :key="item.id" :label="item.projectName" :value="item.id" />
                        </el-select>
                        <el-select v-model="contractId" filterable clearable class="mr-14px w-200px" placeholder="请选择合同段">
                            <el-option v-for="item in contractList" :key="item.id" :label="item.contractName" :value="item.id" />
                        </el-select>
                        <el-button type="info" @click="projectQueryClick">查询</el-button>
                    </div>
                </div>
                <!-- 允许偏差值范围 -->
                <div v-if="formulaCardType === 'range'" class="border-dashed-card hc-formula-card-range mb-14px" :class="isRangeSelectEle ? 'is-h' : ''">
                    <div class="hc-formula-card-range-form hc-flex mb-12px text-14px">
                        <div>允许偏差值范围：</div>
                        <div class="w-130px">
                            <el-select v-model="deviationRangeSymbol" filterable clearable placeholder="请选择允许偏差值范围">
                                <el-option label="【min,max】" value="【min,max】" />
                                <el-option label=">" value=">" />
                                <el-option label="<" value="<" />
                                <el-option label="≥" value="≥" />
                                <el-option label="≤" value="≤" />
                            </el-select>
                        </div>
                        <div class="ml-50px">模式：</div>
                        <div class="mr-50px w-100px">
                            <el-select v-model="deviationRangeResult" filterable clearable placeholder="请选择模式" @change="deviationRangeResultChange">
                                <el-option label="普通" value="1" />
                                <el-option label="自定义" value="2" />
                            </el-select>
                        </div>
                        <div v-if="deviationRangeResult === '1'" class="hc-flex mr-50px">
                            <VueTagsInput
                                v-if="!(deviationRangeSymbol === '<' || deviationRangeSymbol === '≤')"
                                v-model="deviationRangeTag1" :tags="deviationRangeTags1"
                                placeholder="输入/参数" class="mr-12px" :class="curRangeFocusIndex === 1 ? 'cur' : ''"
                                @focus="curRangeFocusIndex = 1"
                                @blur="deviationRangeBlur1" @before-adding-tag="rangeAddingTag"
                            />
                            <VueTagsInput
                                v-if="!(deviationRangeSymbol === '>' || deviationRangeSymbol === '≥')"
                                v-model="deviationRangeTag2" :tags="deviationRangeTags2"
                                placeholder="输入/参数" :class="curRangeFocusIndex === 2 ? 'cur' : ''"
                                @focus="curRangeFocusIndex = 2" @blur="deviationRangeBlur2"
                                @before-adding-tag="rangeAddingTag"
                            />
                        </div>
                        <el-button :type="isRangeSelectEle ? 'primary' : 'info'" @click="deviationRangeSelectEle">选择参数</el-button>
                    </div>
                    <div v-if="deviationRangeResult === '2'" class="hc-formula-card-range-param relative mb-12px">
                        <el-row :gutter="20">
                            <el-col v-if="!(deviationRangeSymbol === '<' || deviationRangeSymbol === '≤')" :span="12">
                                <div class="deviation-range-param-card" :class="curRangeFocusIndex === 3 ? 'cur' : ''" @click.capture="curRangeFocusIndex = 3">
                                    <div class="title-box">参数1</div>
                                    <div class="action-box hc-flex">
                                        <div class="left hc-flex flex-1">
                                            <div class="btn hc-flex-center" @click="resetFunText">
                                                <span class="text">输入值</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunBrackets('(')">
                                                <span class="symbol">(</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunBrackets(')')">
                                                <span class="symbol">)</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('+')">
                                                <i class="i-ri-add-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('-')">
                                                <i class="i-ri-subtract-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('*')">
                                                <i class="i-ri-close-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('%')">
                                                <hc-icon name="divide" />
                                            </div>
                                        </div>
                                        <div class="right hc-flex">
                                            <el-tooltip content="删除元素" placement="top-end">
                                                <div class="btn hc-flex-center" @click="resetFunDel">
                                                    <i class="i-ri-delete-back-2-line" />
                                                </div>
                                            </el-tooltip>
                                            <el-tooltip content="清空所有" placement="top-end">
                                                <div class="btn hc-flex-center" @click="resetFunClear">
                                                    <i class="i-ri-delete-bin-3-line" />
                                                </div>
                                            </el-tooltip>
                                        </div>
                                    </div>
                                    <div class="input-box">
                                        <draggable v-if="selectEleFormula3.length > 0" v-model="selectEleFormula3" item-key="index">
                                            <template #item="{ element }">
                                                <span class="element-class" :class="[`is-${element.type}`, element.selected ? 'is-cur' : '']" @click="selectEleFormulaItem(element)">{{ element.name }}</span>
                                            </template>
                                        </draggable>
                                        <div v-else class="text-gray-5">请选择元素</div>
                                    </div>
                                </div>
                            </el-col>
                            <el-col v-if="!(deviationRangeSymbol === '>' || deviationRangeSymbol === '≥')" :span="12">
                                <div class="deviation-range-param-card" :class="curRangeFocusIndex === 4 ? 'cur' : ''" @click.capture="curRangeFocusIndex = 4">
                                    <div class="title-box">参数2</div>
                                    <div class="action-box hc-flex">
                                        <div class="left hc-flex flex-1">
                                            <div class="btn hc-flex-center" @click="resetFunText">
                                                <span class="text">输入值</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunBrackets('(')">
                                                <span class="symbol">(</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunBrackets(')')">
                                                <span class="symbol">)</span>
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('+')">
                                                <i class="i-ri-add-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('-')">
                                                <i class="i-ri-subtract-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('*')">
                                                <i class="i-ri-close-line" />
                                            </div>
                                            <div class="btn hc-flex-center" @click="resetFunOperator('%')">
                                                <hc-icon name="divide" />
                                            </div>
                                        </div>
                                        <div class="right hc-flex">
                                            <el-tooltip content="删除元素" placement="top-end">
                                                <div class="btn hc-flex-center" @click="resetFunDel">
                                                    <i class="i-ri-delete-back-2-line" />
                                                </div>
                                            </el-tooltip>
                                            <el-tooltip content="清空所有" placement="top-end">
                                                <div class="btn hc-flex-center" @click="resetFunClear">
                                                    <i class="i-ri-delete-bin-3-line" />
                                                </div>
                                            </el-tooltip>
                                        </div>
                                    </div>
                                    <div class="input-box">
                                        <draggable v-if="selectEleFormula4.length > 0" v-model="selectEleFormula4" item-key="index">
                                            <template #item="{ element }">
                                                <span class="element-class" :class="[`is-${element.type}`, element.selected ? 'is-cur' : '']" @click="selectEleFormulaItem(element)">{{ element.name }}</span>
                                            </template>
                                        </draggable>
                                        <div v-else class="text-gray-5">请选择元素</div>
                                    </div>
                                </div>
                            </el-col>
                        </el-row>
                    </div>
                    <div v-if="isRangeSelectEle" class="hc-formula-card-range-select relative">
                        <hc-body split padding="0">
                            <template #left>
                                <hc-card class="hc-formula-card-range-select-left-card" scrollbar :loading="treeResetFunLoading">
                                    <template #header>
                                        <hc-search-input v-model="resetFunTree" @search="resetFunTreeSearch" />
                                    </template>
                                    <el-tree
                                        v-if="isResetFunTreeLazy" ref="treeRangeSelectLazyRef"
                                        :default-expanded-keys="treeResetFunLazyExpanded" node-key="id"
                                        :props="defaultProps" :expand-on-click-node="false" lazy highlight-current
                                        :load="treeResetFunLazyLoad"
                                        @node-click="treeResetFunLazyClick"
                                    />
                                    <el-tree
                                        v-else ref="treeRangeSelectAllRef" :data="resetFunTreeAll" :props="defaultProps" node-key="id"
                                        :expand-on-click-node="false" @node-click="treeResetFunLazyClick"
                                    />
                                </hc-card>
                            </template>
                            <hc-card scrollbar class="hc-formula-card-range-select-right-card">
                                <template #header>
                                    <hc-search-input v-model="resetFunEle" placeholder="请输入你想搜索的元素字段" @search="resetFunEleSearch" />
                                </template>
                                <div v-loading="isResetFunEleLoading" class="body h-full">
                                    <template v-for="(item, index) in resetFunEleData" :key="index">
                                        <el-button v-if="item.k" type="primary" plain size="small" @click="resetFunEleTagClick(item)">{{ item.name }}</el-button>
                                        <el-button v-else type="primary" plain size="small" @click="resetFunEleTagClick(item)">{{ item.eName }}</el-button>
                                    </template>
                                </div>
                            </hc-card>
                        </hc-body>
                    </div>
                </div>
                <!-- 多标签处理 -->
                <div v-if="formulaCardType === 'select-ele'" class="hc-formula-card-tag mb-14px">
                    <hc-body padding="0">
                        <el-tabs v-model="equationSelectIndex" type="border-card" closable :before-leave="leaveEquationSelect" @tab-remove="delEquationSelect">
                            <template v-for="(item, index) in equationSelectEle.children" :key="index">
                                <el-tab-pane :label="item.name" :name="index">
                                    <template v-if="!['日期偏移', '日期格式化', '下标取数', '判断'].includes(item.name)">
                                        <div class="ft mb-6px">{{ getTemplateFt(item) }}</div>
                                        <div class="example mb-14px">{{ item?.example }}</div>
                                        <div class="arguments relative">
                                            <template v-for="(items, indexs) in item.arguments" :key="indexs">
                                                <div class="item hc-flex mb-10px">
                                                    <span>参数{{ indexs + 1 }}({{ item.template.args[indexs].m }})：</span>
                                                    <template v-if="JSON.stringify(items) !== 'null'">
                                                        <el-tag v-if="(typeof items) == 'object' && (['Element', 'ParamData'].includes(items.type))">{{ items.name }}</el-tag>
                                                        <el-input v-else v-model="item.arguments[indexs]" placeholder="请输入内容" class="w-200px" size="small" />
                                                    </template>
                                                    <el-link type="primary" class="ml-12px" @click="enterTextClick(item, indexs)">输入文本</el-link>
                                                    <el-link type="primary" class="ml-12px" @click="selectingElements(index, indexs)">选择元素</el-link>
                                                    <el-link type="primary" class="ml-12px" @click="setCurElement(item, index, indexs)">当前元素</el-link>
                                                </div>
                                            </template>
                                        </div>
                                    </template>
                                    <template v-else-if="['日期偏移', '日期格式化', '下标取数', '判断'].includes(item.name)">
                                        <div class="hc-formula-card-tag-date" :dataForm="setFormulaDataForm(item)">
                                            <div class="hc-flex mb-8px">
                                                <span class="mr-10px">日期增减</span>
                                                <el-button size="small" type="info" @click="tagDateArgSelectEle(index)">选择参数</el-button>
                                            </div>
                                            <div class="relative mb-12px text-orange-6">输入某个固定日期/选择引用某个日期参数+/-固定天数（可选择引用某个参数值，也可输入固定值）</div>
                                            <div class="hc-flex">
                                                <el-tag v-if="tagDateArgName0" closable @close="delTagDateArgEle(item, '0')">{{ tagDateArgName0 }}</el-tag>
                                                <el-input v-else value="" placeholder="引用参数名称" size="small" class="w-100px" @focus="curTagDateFocus(1)" />
                                                <div class="hc-flex ml-10px mr-10px text-20px">/</div>
                                                <div class="hc-flex w-160px">
                                                    <el-date-picker v-model="tagDateArgDate0" class="block" type="date" size="small" placeholder="选择日期" format="YYYY 年 MM 月 dd 日" value-format="YYYY-MM-dd" @change="tagArgDateChange($event, item)" />
                                                </div>
                                                <el-select v-model="tagDateArgOperator" placeholder="请选择" size="small" class="ml-10px mr-10px w-50px" @change="tagDateArgOperatorChange($event, item)">
                                                    <el-option label="+" value="+" />
                                                    <el-option label="-" value="-" />
                                                </el-select>
                                                <el-tag v-if="tagDateArgName1" closable @close="delTagDateArgEle(item, '1')">{{ tagDateArgName1 }}</el-tag>
                                                <el-input v-else value="" size="small" placeholder="参数名称" class="w-100px" @focus="curTagDateFocus(2)" />
                                                <div class="hc-flex ml-10px mr-10px text-20px">/</div>
                                                <el-input v-model="tagDateArgDate1" placeholder="输入值" size="small" class="w-100px" @change="tagDateArgChange($event, item)" />
                                            </div>
                                        </div>
                                    </template>
                                </el-tab-pane>
                            </template>
                        </el-tabs>
                    </hc-body>
                </div>
            </div>
            <template #action>
                <el-button @click="drawerClose">取消</el-button>
                <el-button type="primary" :loading="submitLoading" @click="submitClick">保存</el-button>
            </template>
        </hc-card>
        <!-- 手写模式 -->
        <hc-dialog v-model="isHandWritEle" is-table widths="900px" title="手写模式" @close="handWritEleClose">
            <template #search>
                <div class="relative">
                    <div class="mb-6px text-orange-6">tips:手写模式不保证能转换成配置模式！！即使能转换也不保证正确！！！</div>
                    <div class="text-orange-6">无法在手写模式手写加入新的元素！新的节点参数！</div>
                </div>
            </template>
            <el-input v-model="handWritText" type="textarea" class="hc-formula-hand-writ-text" placeholder="请输入内容" />
            <template #footer>
                <el-button hc-btn @click="handWritEleClose">取消</el-button>
                <el-button hc-btn type="primary" @click="handWritTransform">转换</el-button>
            </template>
        </hc-dialog>
        <!-- 选择元素 -->
        <hc-dialog v-model="isSelectElementShow" is-table widths="1200px" title="选择元素" :footer="false" @close="selectElementClose">
            <hc-body split class="hc-formula-card-select-ele-dialog">
                <template #left>
                    <hc-card class="hc-formula-card-range-select-left-card" scrollbar :loading="treeResetFunLoading">
                        <template #header>
                            <hc-search-input v-model="resetFunTree" @search="resetFunTreeSearch" />
                        </template>
                        <el-tree
                            v-if="isResetFunTreeLazy" ref="treeRangeSelectLazyRef"
                            :default-expanded-keys="treeResetFunLazyExpanded" node-key="id"
                            :props="defaultProps" :expand-on-click-node="false" lazy highlight-current
                            :load="treeResetFunLazyLoad"
                            @node-click="treeResetFunLazyClick"
                        />
                        <el-tree
                            v-else ref="treeRangeSelectAllRef" :data="resetFunTreeAll" :props="defaultProps" node-key="id"
                            :expand-on-click-node="false" @node-click="treeResetFunLazyClick"
                        />
                    </hc-card>
                </template>
                <hc-card scrollbar class="hc-formula-card-range-select-right-card">
                    <template #header>
                        <hc-search-input v-model="resetFunEle" placeholder="请输入你想搜索的元素字段" @search="resetFunEleSearch" />
                    </template>
                    <div v-loading="isResetFunEleLoading" class="body h-full">
                        <template v-for="(item, index) in resetFunEleData" :key="index">
                            <el-button v-if="item.k" type="primary" plain size="small" @click="setSelectElement(item)">{{ item.name }}</el-button>
                            <el-button v-else type="primary" plain size="small" @click="setSelectElement(item)">{{ item.eName }}</el-button>
                        </template>
                    </div>
                </hc-card>
            </hc-body>
        </hc-dialog>
    </hc-drawer>
</template>

<script setup>
import { nextTick, ref, watch } from 'vue'
import { useClick } from 'hc-vue3-ui'
import {
    arrIndex, deepClone, getArrValue, getObjVal, getObjValue,
    getRandom, isArray, isNullES, isString,
} from 'js-fast-way'
import { ElMessageBox } from 'element-plus'
import { VueTagsInput } from '@vojtechlanka/vue-tags-input'
import draggable from 'vuedraggable'

//辅助解析文件
import { rangeToString } from './formula/rangeToString'
import { formulaArrayToString } from './formula/formulaArrayToString'
import { formulaStringToArray } from './formula/formulaStringToArray'

//接口文件
import projectApi from '~api/project/project'
import contractApi from '~api/project/contract'
import formulaApi from '~api/project/formula'
import elementApi from '~api/project/element'
import privateApi from '~api/wbs/private'
import treeApi from '~api/wbs/tree'

const props = defineProps({
    data: {
        type: Object,
        default: () => ({}),
    },
})

//事件
const emit = defineEmits(['close', 'finish', 'uncheck'])

//双向绑定
const isShow = defineModel('modelValue', {
    default: false,
})

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

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

//基础变量
const symbolReg = /(\+|-|\*|\/)（.+）/ //加减乘除
const operatorReg = /^\+|-|\*|%/ //加减乘除
const startFCRegExp = /^FC\.([a-zA-Z\d]+)\(/ //匹配开始的FC.xxx(
const isScrollBar = ref(true)

//获取数据
const cardFormulaTitle = ref('')
const getDataApi = async () => {
    const { cardTitle } = getObjValue(dataInfo.value)
    cardFormulaTitle.value = cardTitle
    await getTypeMapApi()
    await getWbsFormElementData()
    await getFormulaStringToArrayApi()
    getProjectDataApi().then()
}

//保留位数
const isRetain = ref(false)
const retainNum = ref(2)
const formulaCardType = ref('project')

//把公式文本还原数组
const rightDict = ref([])
const formulaId = ref('')
const deviationRangeObj = ref({})
const getFormulaStringToArrayApi = async () => {
    const { eleId, globalType, nodeId, pid } = getObjValue(dataInfo.value)
    const { code, data } = await formulaApi.detail({
        projectId: pid,
        elementId: eleId,
        nodeId: nodeId,
        scope: globalType,
    })
    if (code !== 200) return
    const res = getObjValue(data)
    console.log(res)
    if (!isNullES(res.id)) {
        //获取右边元素的字典
        let dictMap = getObjValue(res.dict), dictArr = []
        //遍历
        for (let i in dictMap) {
            dictArr.push(dictMap[i])
        }
        rightDict.value = dictArr
        formulaId.value = res.id
        //把公式字符串还原成数组
        let formula = formulaStringToArray(res.formula, res.map, formulaMenuMap.value)
        processFormula.value = getArrValue(formula?.processFormula)
        const results = resultFormula.value
        formula.resultFormula[0].id = results[0].id
        formula.resultFormula[0].name = results[0].name
        formula.resultFormula[0].tableElementKey = results[0].tableElementKey
        resultFormula.value[0].children = formula.resultFormula[0].children
        //允许偏差值范围
        let mapObj = JSON.parse(res.map)
        if (mapObj.deviationRangeJson) {
            deviationRangeObj.value = JSON.parse(mapObj.deviationRangeJson)
        }
    }
    if (res.scale >= 0) {
        isRetain.value = true
        retainNum.value = res.scale
    } else {
        isRetain.value = false
        retainNum.value = 2
    }
}

//获取当前元素的表名
const getItemTableName = (item) => {
    if (item.type !== 'Element') {
        return
    }
    rightDict.value.forEach((ele) => {
        if (ele.ekey === item.tableElementKey) {
            item.tableName = ele.tableName
        }
    })
}

//允许偏差值范围
const setDeviationRange = () => {
    const cardType = formulaCardType.value
    if (cardType === 'range') {
        curRangeFocusIndex.value = 0
        formulaCardType.value = 'project'
        return
    }
    formulaCardType.value = 'range'
    const { symbol, model, arguments1, arguments2 } = deviationRangeObj.value
    deviationRangeSymbol.value = symbol
    deviationRangeResult.value = model
    curRangeFocusIndex.value = 1
    //公式
    if (isArray(arguments1) && arguments1.length > 1 || isArray(arguments2) && arguments2.length > 1) {
        //selectEleFormula.value = arguments1
        selectEleFormula3.value = arguments1
        selectEleFormula4.value = arguments2
        return
    }
    //参数1
    if (isString(arguments1)) {
        deviationRangeTag1.value = arguments1
    } else {
        deviationRangeTags1.value = arguments1
    }
    //参数2
    if (isString(arguments2)) {
        deviationRangeTag2.value = arguments2
    } else {
        deviationRangeTags2.value = arguments2
    }
}

//获取顶部菜单数据
const formulaMenuMap = ref({})
const formulaMenuIndex = ref(null)
const formulaMenuList = ref({})
const getTypeMapApi = async () => {
    const { data } = await formulaApi.getTypeMap()
    const res = getObjValue(data)
    formulaMenuList.value = deepClone(res)
    //生成map，方便查找
    for (let key in res) {
        if (typeof (res[key]) === 'object') {
            res[key].forEach((formula) => {
                formula.template = JSON.parse(formula.template)
                if (operatorReg.test(formula.template.ft)) {
                    formulaMenuMap.value[formula.template.ft] = formula
                } else if (startFCRegExp.test(formula.template.ft)) {
                    let regRes = formula.template.ft.match(startFCRegExp)
                    formulaMenuMap.value[regRes[0]] = formula
                }
            })
        }
    }
}

//菜单被选择
const equationSelectEle = ref({})
const equationSelectEleCopy = ref({})
const handleFormulaMenu = async (index, path) => {
    const cardType = formulaCardType.value
    if (cardType === 'reset-fun') {
        //重置函数
        if (path[0] !== '基础运算') {
            window?.$message.warning('当前只能使用基础运算')
            return
        }
        try {
            let indexs = Number(path[1].split('-')[1]) - 1
            const item = formulaMenuList.value[path[0]][indexs]
            const val = symbolReg.exec(item.name)[1]
            resetFunOperator(val)
        } catch (e) {
            console.error(e)
        }
    } else {
        const data = await getEquationSelectEle()
        equationSelectEle.value = getObjValue(data)
        await equationSelect(path)
        //深拷贝数据
        equationSelectEleCopy.value = deepClone(equationSelectEle.value)
        //是否有滚动条
        const newEle = await isSelectEle()
        isScrollBar.value = !newEle
        if (newEle) {
            formulaCardType.value = 'select-ele'
        }
    }
}

//在等式模式下点选计算式
const equationSelectIndex = ref(-1)
const equationSelect = async (path) => {
    const selectEle = getObjVal(equationSelectEle.value)
    if (!selectEle || !['Element', 'ParamData'].includes(selectEle.type)) {
        window?.$message.warning('请先选中元素')
        return
    }
    let obj = {}
    try {
        const index = Number(path[1].split('-')[1]) - 1
        const expression = formulaMenuList.value[path[0]][index]
        obj = deepClone(expression)
        obj.template = isNullES(obj.template) ? {} : JSON.parse(obj.template)
    } catch (error) {
        console.log(error)
    }
    if (obj.type === 1) return
    obj.arguments = new Array(obj.template.args.length)
    let ele = {}
    if (selectEle.type === 'ParamData') {
        ele = {
            type: 'ParamData',
            id: selectEle.id,
            v: selectEle.v,
            k: selectEle.k,
            name: selectEle.name,
            selected: false,
        }
    } else {
        ele = {
            type: 'Element',
            id: selectEle.id,
            name: selectEle.name,
            selected: false,
            tableElementKey: selectEle.tableElementKey,
        }
    }
    let tg = obj.template.args.findIndex(x => x.m !== '常量')
    obj.arguments[tg] = ele
    equationSelectEle.value.children.push(obj)
    //跳转到最新的标签
    equationSelectIndex.value = equationSelectEle.value.children.length - 1
}

//获取当前选中的元素
const getEquationSelectEle = async () => {
    const type = processType.value
    if (isNullES(type)) return null
    const index = processIndex.value
    let arr = []
    if (type === 'resultFormula') {
        arr = resultFormula.value
    } else if (type === 'processFormula') {
        arr = processFormula.value
    }
    if (arr.length <= 0) return null
    return arr[index]
}

const isSelectEle = async () => {
    if (isNullES(equationSelectEle.value)) return false
    if (isNullES(equationSelectEle.value.children)) return false
    return equationSelectEle.value.children.length > 0
}

//移除挂载的函数
const delEquationSelect = (name) => {
    equationSelectEle.value?.children?.splice(Number(name), 1)
    const data = getArrValue(equationSelectEle.value?.children)
    if (data.length <= 0) {
        formulaCardType.value = 'project'
        equationSelectIndex.value = -1
        equationSelectEle.value = {}
        equationSelectEleCopy.value = {}
    }
}

//切换公式tab标签
const leaveEquationSelect = (name, oldName) => {
    if (isNullES(oldName)) return false
    let formula = equationSelectEle.value?.children[Number(oldName)]
    if (isNullES(formula)) return false
    return checkFormulaLegal(formula)
}

//检测公式合法
const checkFormulaLegal = (formula) => {
    if (!formula.arguments) return false
    //当前选中的元素
    let curEle = equationSelectEle.value, isIn = false
    for (let i = 0; i < formula.arguments.length; i++) {
        if (Array.isArray(formula.arguments[i])) {
            for (let j = 0;j < formula.arguments[i].length;j++) {
                if (formula.arguments[i][j] && formula.arguments[i][j].id == curEle.id) {
                    isIn = true
                    break
                }
            }
            if (isIn) break
        } else if (formula.arguments[i] && formula.arguments[i].id == curEle.id) {
            isIn = true
            break
        }
    }
    if (!isIn) {
        window?.$message.warning('参数必须有一个值是当前元素')
        return false
    }
    return true
}

//获取数据
const resultFormula = ref([])
const getWbsFormElementData = async () => {
    const { eleId } = getObjValue(dataInfo.value)
    resultFormula.value = []
    if (isNullES(eleId)) return
    const { data } = await elementApi.detail(eleId)
    const obj = getObjValue(data)
    resultFormula.value = [{
        type: 'Element',
        name: obj.eName,
        id: obj.id,
        selected: false,
        tableElementKey: obj.tableElementKey,
        children: [],
    }]
}

//左边被点击
const processIndex = ref(-1)
const processType = ref('')
const resultFormulaItem = (item, index) => {
    clearResetFunClick()
    //设置当前选中
    processIndex.value = index
    processType.value = 'resultFormula'
    item.selected = true
}

//右边被点击
const processFormulaItem = (item, index) => {
    clearResetFunClick()
    //设置当前选中
    processIndex.value = index
    processType.value = 'processFormula'
    item.selected = true
}

//清除选择
const clearResetFunClick = () => {
    //清除左边的选中
    resultFormula.value.forEach((obj) => {
        obj.selected = false
    })
    //清除右边的选中
    processFormula.value.forEach((obj) => {
        obj.selected = false
    })
    //设置当前选中
    processIndex.value = -1
    processType.value = ''
}

//是否重置函数
const resetFunClick = () => {
    const cardType = formulaCardType.value
    if (cardType === 'reset-fun') {
        curRangeFocusIndex.value = 0
        formulaCardType.value = 'project'
        isScrollBar.value = true
    } else {
        formulaCardType.value = 'reset-fun'
        curRangeFocusIndex.value = 99
        isScrollBar.value = false
    }
}

//tree树配置
const defaultProps = {
    label: 'title',
    children: 'children',
    isLeaf: (data) => {
        return !data.hasChildren
    },
}

//重置函数懒加载树
const treeResetFunLazyRef = ref(null)
const treeRangeSelectLazyRef = ref(null)
const treeResetFunAllRef = ref(null)
const treeRangeSelectAllRef = ref(null)
const treeResetFunLazyExpanded = ref([])

//获取重置函数懒加载树的数据
const treeResetFunLoading = ref(false)
const treeResetFunLazyLoad = async (node, resolve) => {
    const { level, data } = node
    treeResetFunItemData.value = data
    let parentId = level !== 0 ? data.id : 12345678910
    const { eleType, node: dataNode, tableType, pid } = getObjValue(dataInfo.value)
    const treeNode = getObjValue(dataNode)
    if (level === 0) treeResetFunLoading.value = true
    if (!eleType) {
        //获取接口数据
        const { data } = await privateApi.tabTypeLazyTreeAll({
            parentId,
            current: 1,
            size: 99999,
            hasPartFormula: treeNode.hasPartFormula,
        })
        const res = getArrValue(data.records)
        treeResetFunLoading.value = false
        resolve(res)
        //处理返回的数据
        await nextTick()
        //处理展开
        try {
            const expandId = tableType ? Number(treeNode.tableType) - 1 : Number(treeNode.parentId) - 1
            if (!isNullES(expandId) && expandId >= 0) node.childNodes[expandId].expand()
        } catch { /* empty */
        }
        //处理选中
        try {
            const paramsId = treeNode.initTableId
            if (!isNullES(paramsId)) {
                treeResetFunLazyRef.value?.setCurrentKey(paramsId)
                treeRangeSelectLazyRef.value?.setCurrentKey(paramsId)
            }
        } catch { /* empty */
        }
        //获取节点详情
        await getNodeDetailApi(treeNode)
    } else if (eleType) {
        //获取接口数据
        const { data } = await privateApi.tabTypeLazyTree({
            parentId,
            projectId: pid,
            pcurrent: 1,
            size: 99999,
        })
        const res = getArrValue(data.records)
        treeResetFunLoading.value = false
        resolve(res)
        //处理返回的数据
        await nextTick()
        //处理展开
        try {
            let expandId = Number(treeNode.parentId) - 1
            if (!isNullES(expandId) && expandId >= 0) node.childNodes[expandId].expand()
        } catch { /* empty */
        }
        //处理选中
        try {
            const paramsId = treeNode.id
            if (!isNullES(paramsId)) {
                treeResetFunLazyRef.value?.setCurrentKey(paramsId)
                treeRangeSelectLazyRef.value?.setCurrentKey(paramsId)
            }
        } catch { /* empty */
        }
        //获取节点详情
        await getNodeDetailApi(treeNode)
    }
}

//重置函数懒加载树点击
const treeResetFunItemData = ref({})
const treeResetFunNodeData = ref({})
const treeResetFunLazyClick = async (data, node) => {
    treeResetFunItemData.value = data
    treeResetFunNodeData.value = node
    await getNodeDetailApi(data)
}

//重置函数树搜索
const resetFunTree = ref('')
const resetFunTreeAll = ref([])
const isResetFunTreeLazy = ref(true)
const resetFunTreeSearch = async () => {
    if (isNullES(resetFunTree.value)) {
        isResetFunTreeLazy.value = true
        return
    }
    const { eleType, node: dataNode, tableType, pid } = getObjValue(dataInfo.value)
    if (!eleType) {
        isResetFunTreeLazy.value = false
        treeResetFunLoading.value = true
        const obj = treeResetFunItemData.value
        const parentId = obj.hasChildren ? obj.id : ''
        const { data, code } = await privateApi.tabTypeLazyTreeAll({
            parentId: parentId,
            current: 1,
            size: 1000,
            titleName: resetFunTree.value,
        })
        if (code !== 200) {
            resetFunTreeAll.value = []
            treeResetFunLoading.value = false
            return
        }
        resetFunTreeAll.value = getArrValue(data?.records)
        treeResetFunLoading.value = false
    } else if (eleType) {
        isResetFunTreeLazy.value = false
        treeResetFunLoading.value = true
        const obj = treeResetFunItemData.value
        const parentId = obj.hasChildren ? obj.id : ''
        const { data, code } = await privateApi.tabTypeLazyTree({
            parentId: parentId,
            current: 1,
            size: 1000,
            titleName: resetFunTree.value,
        })
        if (code !== 200) {
            resetFunTreeAll.value = []
            treeResetFunLoading.value = false
            return
        }
        resetFunTreeAll.value = getArrValue(data?.records)
        treeResetFunLoading.value = false
    }
}

//重置函数元素搜索
const resetFunEle = ref('')
const isResetFunEleLoading = ref(false)
const resetFunEleSearch = async () => {
    const { initTableId } = treeResetFunItemData.value
    if (isNullES(initTableId)) {
        resetFunEleData.value = []
        isResetFunEleLoading.value = false
        return
    }
    isResetFunEleLoading.value = true
    if (isNullES(resetFunEle.value)) {
        const { data } = await treeApi.getTableElments({
            id: initTableId,
        })
        resetFunEleData.value = getArrValue(data)
    } else {
        const { data } = await treeApi.getTableElments({
            id: initTableId,
            search: resetFunEle.value,
        })
        resetFunEleData.value = getArrValue(data)
    }
    isResetFunEleLoading.value = false
}

//获取节点详情
const resetFunEleData = ref([])
const getNodeDetailApi = async (item) => {
    await useClick(300)
    if (isNullES(item.initTableId)) {
        resetFunEleData.value = []
        isResetFunEleLoading.value = false
        return
    }
    if (item.hasChildren === false || item.isLinkTable === 2) {
        isResetFunEleLoading.value = true
        const { data } = await treeApi.getTableElments({
            id: item.initTableId,
        })
        resetFunEleData.value = getArrValue(data)
    } else {
        resetFunEleData.value = []
    }
    isResetFunEleLoading.value = false
}

//元素字段被点击
const selectEleFormula = ref([])
const selectEleFormula3 = ref([])
const selectEleFormula4 = ref([])
const resetFunEleTagClick = (item) => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    let arr = []
    if (index === 99) {
        //重置函数
        arr = selectEleFormula.value
    } else if (index === 3) {
        //参数1
        arr = selectEleFormula3.value
    } else if (index === 4) {
        //参数2
        arr = selectEleFormula4.value
    }
    let { type, name } = getObjValue(arr[arr.length - 1])
    if (type === 'Text') {
        window?.$message.warning('元素无法连续出现在输入值后面')
        return
    }
    if (type === 'Brackets' && name === ')') {
        window?.$message.warning('元素无法连续出现在右括号后面')
        return
    }
    if (arr.length === 0 || ['Operator', 'Brackets'].includes(type) || name === '(') {
        if (!isNullES(item.tableElementKey)) {
            const obj = {
                type: 'Element',
                name: item.eName,
                id: item.id,
                selected: false,
                tableElementKey: item.tableElementKey,
                index: getRandom(5),
                children: [],
            }
            if (index === 99) {
                selectEleFormula.value.push(obj)
            } else if (index === 3) {
                selectEleFormula3.value.push(obj)
            } else if (index === 4) {
                selectEleFormula4.value.push(obj)
            }
        }
    } else {
        window?.$message.warning('当前操作不符合要求')
    }
}

//输入弹窗
const promptMessageBox = async () => {
    return new Promise(resolve => {
        ElMessageBox.prompt('', '请输入值', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            inputErrorMessage: '请输入内容',
            inputValidator: (value) => {
                return !isNullES(value)
            },
        }).then(({ value }) => {
            resolve(value)
        }).catch(() => {
            resolve()
        })
    })
}

//输入值
const resetFunText = async () => {
    const val = await promptMessageBox()
    if (isNullES(val)) return
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    //获取数组
    let arr = []
    if (index === 99) {
        //重置函数
        arr = selectEleFormula.value
    } else if (index === 3) {
        //参数1
        arr = selectEleFormula3.value
    } else if (index === 4) {
        //参数2
        arr = selectEleFormula4.value
    }
    if (arr.length > 0) {
        let { type, name } = getObjValue(arr[arr.length - 1])
        if (type === 'Element') {
            window?.$message.warning('输入值无法连续出现在元素后面')
            return
        }
        if (type === 'Text') {
            window?.$message.warning('输入值无法连续出现在输入值后面')
            return
        }
        if (type === 'Brackets' && name === ')') {
            window?.$message.warning('输入值无法连续出现在右括号后面')
            return
        }
    }
    //公共对象
    const obj = {
        type: 'Text',
        name: val,
        selected: false,
        index: getRandom(5),
    }
    if (index === 99) {
        selectEleFormula.value.push(obj)
    } else if (index === 3) {
        selectEleFormula3.value.push(obj)
    } else if (index === 4) {
        selectEleFormula4.value.push(obj)
    }
}

//括号
const resetFunBrackets = (val) => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    //公共对象
    const obj = {
        type: 'Brackets',
        name: val,
        selected: false,
        index: getRandom(5),
    }
    if (index === 99) {
        //重置函数
        selectEleFormula.value.push(obj)
    } else if (index === 3) {
        //参数1
        selectEleFormula3.value.push(obj)
    } else if (index === 4) {
        //参数2
        selectEleFormula4.value.push(obj)
    }
}

//运算符
const resetFunOperator = (val) => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    //获取数组
    let arr = []
    if (index === 99) {
        //重置函数
        arr = selectEleFormula.value
    } else if (index === 3) {
        //参数1
        arr = selectEleFormula3.value
    } else if (index === 4) {
        //参数2
        arr = selectEleFormula4.value
    }
    const map = formulaMenuMap.value
    if (arr.length <= 0) {
        window?.$message.warning('公式开头不能是运算符号')
        return
    }
    let { type, name } = getObjValue(arr[arr.length - 1])
    if (type === 'Operator') {
        window?.$message.warning('运算符号无法连续出现在运算符号后面')
        return
    }
    if (type === 'Brackets' && name === '(') {
        window?.$message.warning('运算符号无法连续出现在左括号后面')
        return
    }
    const obj = getObjValue(map[val])
    //公共对象
    const data = {
        type: 'Operator',
        name: symbolReg.exec(obj.name)[1],
        selected: false,
        template: obj.template,
        index: getRandom(5),
    }
    if (index === 99) {
        selectEleFormula.value.push(data)
    } else if (index === 3) {
        selectEleFormula3.value.push(data)
    } else if (index === 4) {
        selectEleFormula4.value.push(data)
    }
}

//删除
const resetFunDel = () => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    //获取数组
    let arr = []
    if (index === 99) {
        //重置函数
        arr = selectEleFormula.value
    } else if (index === 3) {
        //参数1
        arr = selectEleFormula3.value
    } else if (index === 4) {
        //参数2
        arr = selectEleFormula4.value
    }
    const newArr = deepClone(arr)
    if (newArr.length <= 0) {
        window?.$message.warning('请先添加相关元素')
        return
    }
    const indexs = arrIndex(newArr, 'selected', true)
    if (indexs !== -1) {
        newArr.splice(indexs, 1)
        if (index === 99) {
            selectEleFormula.value = newArr
        } else if (index === 3) {
            selectEleFormula3.value = newArr
        } else if (index === 4) {
            selectEleFormula4.value = newArr
        }
    } else {
        newArr.splice(newArr.length - 1, 1)
        if (index === 99) {
            selectEleFormula.value = newArr
        } else if (index === 3) {
            selectEleFormula3.value = newArr
        } else if (index === 4) {
            selectEleFormula4.value = newArr
        }
    }
}

//清空
const resetFunClear = () => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    if (index === 99) {
        //重置函数
        selectEleFormula.value = []
    } else if (index === 3) {
        //参数1
        selectEleFormula3.value = []
    } else if (index === 4) {
        //参数2
        selectEleFormula4.value = []
    }
}

//被点击
const selectEleFormulaItem = (item) => {
    const index = curRangeFocusIndex.value
    if (index <= 0) {
        window?.$message.warning('非正常操作')
        return
    }
    //获取数组
    let arr = []
    if (index === 99) {
        //重置函数
        arr = selectEleFormula.value
    } else if (index === 3) {
        //参数1
        arr = selectEleFormula3.value
    } else if (index === 4) {
        //参数2
        arr = selectEleFormula4.value
    }
    for (let i = 0; i < arr.length; i++) {
        if (item.index === arr[i].index) {
            arr[i].selected = !arr[i].selected
        } else {
            arr[i].selected = false
        }
    }
    if (index === 99) {
        selectEleFormula.value = arr
    } else if (index === 3) {
        selectEleFormula3.value = arr
    } else if (index === 4) {
        selectEleFormula4.value = arr
    }
}

//赋值给等号右边的数组
const processFormula = ref([])
const setProcessFormula = () => {
    const arr = selectEleFormula.value
    let leftNum = 0, rightNum = 0
    arr.forEach(({ type, name }) => {
        if (type === 'Brackets') {
            if (name === '(') {
                leftNum++
            } else if (name === ')') {
                rightNum++
            }
        }
    })
    if (leftNum !== rightNum) {
        window?.$message.warning('左右括号数量不相等,请先检查是否正确')
        return
    }
    processFormula.value = deepClone(arr)
    formulaCardType.value = 'project'
    isScrollBar.value = true
}

//获取项目数据
const projectId = ref('')
const projectList = ref([])
const getProjectDataApi = async () => {
    const { data } = await projectApi.page({
        current: 1,
        size: 99999,
    })
    projectList.value = getArrValue(data?.records)
}

//项目被选择
const contractId = ref('')
const contractList = ref([])
const projectChange = async () => {
    contractId.value = ''
    const { data } = await contractApi.getList(projectId.value)
    contractList.value = getArrValue(data)
}

//项目查询
const projectQueryClick = () => {
    console.log('原来就没做这个功能')
}

//允许偏差值范围
const deviationRangeSymbol = ref('【min,max】')

//模式切换
const deviationRangeResult = ref('1')
const deviationRangeResultChange = () => {
    if (deviationRangeResult.value === '1') {
        if (!['<', '≤'].includes(deviationRangeSymbol.value)) {
            curRangeFocusIndex.value = 1
        } else if (!['>', '≥'].includes(deviationRangeSymbol.value)) {
            curRangeFocusIndex.value = 2
        }
    } else if (deviationRangeResult.value === '2') {
        if (!['<', '≤'].includes(deviationRangeSymbol.value)) {
            curRangeFocusIndex.value = 3
        } else if (!['>', '≥'].includes(deviationRangeSymbol.value)) {
            curRangeFocusIndex.value = 4
        }
    }
}

//允许偏差值范围1
const deviationRangeTag1 = ref('')
const deviationRangeTags1 = ref([])
const deviationRangeBlur1 = () => {
    if (deviationRangeTag1.value) {
        if (deviationRangeTag1.value && deviationRangeTags1.value[0]) {
            emit('uncheck', deviationRangeTags1.value[0].id)
        }
        deviationRangeTags1.value = []
    }
}

//允许偏差值范围2
const deviationRangeTag2 = ref('')
const deviationRangeTags2 = ref([])
const deviationRangeBlur2 = () => {
    if (deviationRangeTag2.value) {
        if (deviationRangeTag2.value && deviationRangeTags2.value[0]) {
            emit('uncheck', deviationRangeTags2.value[0].id)
        }
        deviationRangeTags2.value = []
    }
}

//当前在哪个输入框
const curRangeFocusIndex = ref(0)
const rangeAddingTag = () => {
    console.log('原来的版本就啥也没做')
}

//选择参数
const isRangeSelectEle = ref(false)
const deviationRangeSelectEle = () => {
    const val = !isRangeSelectEle.value
    isRangeSelectEle.value = val
    isScrollBar.value = !val
}

//手写模式
const handWritText = ref('')
const handWritEleMap = ref({})
const isHandWritEle = ref(false)
const handWritClick = () => {
    try {
        let { text, eleMap } = formulaArrayToString(processFormula.value, resultFormula.value)
        handWritText.value = text
        handWritEleMap.value = JSON.stringify(eleMap)
        isHandWritEle.value = true
    } catch (error) {
        console.log(error)
        window?.$message.error('生成公式文本失败')
    }
}

//手写模式转换
const handWritTransform = () => {
    try {
        let formula = formulaStringToArray(handWritText.value, handWritEleMap.value, formulaMenuMap.value)
        processFormula.value = getArrValue(formula.processFormula)
        const results = resultFormula.value
        formula.resultFormula[0].id = results[0].id
        formula.resultFormula[0].name = results[0].name
        formula.resultFormula[0].tableElementKey = results[0].tableElementKey
        resultFormula.value[0].children = formula.resultFormula[0].children
        handWritEleClose()
    } catch (error) {
        console.log(error)
        window?.$message.error('转成配置用的数组失败')
    }
}

//手写模式关闭
const handWritEleClose = () => {
    isHandWritEle.value = false
    handWritText.value = ''
    handWritEleMap.value = {}
}

const findNumber = (array) => {
    for (const item of array) {
        if (!item.children) continue
        const child = item.children.find(child => child.number)
        if (child) return child.number
    }
    return ''
}

//获取元素
const getTemplateFt = (item) => {
    let template = item?.template?.ft
    item.template.args.forEach(obj => {
        template = template.replace(obj.key, obj.m)
    })
    return template
}

//输入文本
const enterTextClick = (item, indexs) => {
    item.arguments[indexs] = ''
}

//选择元素
const elementsIndex = ref({})
const isSelectElementShow = ref(false)
const selectingElements = (index, indexs) => {
    elementsIndex.value = { indexs: indexs, index: index }
    isSelectEleType.value = 'select'
    isSelectElementShow.value = true
}

//选择了元素
const setSelectElement = (item) => {
    const type = isSelectEleType.value
    if (type === 'select') {
        const { index, indexs } = elementsIndex.value
        try {
            const elementKey = item['tableElementKey'].replace('_key', ':key')
            equationSelectEle.value.children[index].arguments[indexs] = {
                id: item.id,
                type: 'Element',
                selected: false,
                tableElementKey: elementKey,
                name: item.k ? item.name : item.eName,
            }
        } catch (error) {
            console.log(error)
        }
    } else if (type === 'date') {
        setTagDateArgEle(item)
    }
    selectElementClose()
}

//选择元素 关闭
const selectElementClose = () => {
    isSelectElementShow.value = false
    isSelectEleType.value = ''
    selectTagDateIndex.value = -1
}

//当前元素
const setCurElement = (item, index, indexs) => {
    let tmp = deepClone(equationSelectEleCopy.value)
    tmp['tableElementKey'] = tmp['tableElementKey'].replace('_key', ':key')
    item.arguments[indexs] = tmp.children[index].arguments[indexs]
}

//获取数据
const tagDateArgName0 = ref('')
const tagDateArgDate0 = ref(null)
const tagDateArgName1 = ref('')
const tagDateArgDate1 = ref('')
const setFormulaDataForm = (item) => {
    let arg0 = item.arguments[0], arg1 = item.arguments[1]
    // 第一个参数
    if (isDataFormELe(arg0)) {
        tagDateArgName0.value = arg0.name
    } else {
        tagDateArgDate0.value = arg0
    }
    // 第二个参数
    if (isDataFormELe(arg1)) {
        tagDateArgName1.value = arg1.name
    } else {
        tagDateArgDate1.value = arg1
    }
}

const isDataFormELe = (ele) => {
    return typeof ele == 'object' && ele != null
}

//删除
const delTagDateArgEle = (item, type) => {
    if (type === '0') {
        tagDateArgName0.value = ''
        item.arguments[0] = ''
    } else if (type === '1') {
        tagDateArgName1.value = ''
        item.arguments[1] = ''
    }
}

// 焦点
const curTagDateIndex = ref(0)
const curTagDateFocus = (type) => {
    curTagDateIndex.value = type
}

// 选择日期
const tagArgDateChange = (val, item) => {
    tagDateArgName0.value = ''
    item.arguments[0] = val
}

// 选择运算符
const tagDateArgOperator = ref('+')
const tagDateArgOperatorChange = (val, item) => {
    const date1 = tagDateArgDate1.value || ''
    if (isNullES(date1)) {
        item.arguments[1] = date1
        return
    }
    if (!isDataFormELe(item.arguments[1])) {
        if (val === '-') {
            item.arguments[1] = val + date1
        } else {
            item.arguments[1] = date1
        }
    }
}

const tagDateArgChange = (val, item) => {
    tagDateArgName1.value = ''
    item.arguments[1] = val
}

//选择参数
const isSelectEleType = ref('')
const selectTagDateIndex = ref(-1)
const tagDateArgSelectEle = (index) => {
    isSelectEleType.value = 'date'
    selectTagDateIndex.value = index
    isSelectElementShow.value = true
}

//设置
const setTagDateArgEle = (item) => {
    const type = curTagDateIndex.value
    if (isNullES(type) || type <= 0) return
    const index = selectTagDateIndex.value
    let obj = {
        id: item.id,
        selected: false,
        type: 'Element',
        name: item.eName,
        tableElementKey: item.tableElementKey,
        children: [],
    }
    if (type === 1) {
        equationSelectEle.value.children[index].arguments[0] = obj
        tagDateArgName0.value = obj.name
        tagDateArgDate0.value = null
    } else if (type === 2) {
        equationSelectEle.value.children[index].arguments[1] = obj
        tagDateArgName1.value = obj.name
        tagDateArgDate1.value = ''
    }
}

//保存
const submitLoading = ref(false)
const submitClick = async () => {
    const cardType = formulaCardType.value
    //重置函数
    if (cardType === 'reset-fun') {
        setProcessFormula()
        return
    }
    //允许偏差值范围
    submitLoading.value = true
    const result = deviationRangeResult.value
    deviationRangeObj.value = {
        symbol: deviationRangeSymbol.value,
        model: result,
        arguments1: result === '2' ? selectEleFormula3.value : deviationRangeTag1.value,
        arguments2: result === '2' ? selectEleFormula4.value : deviationRangeTag2.value,
    }
    //处理数据
    const process = processFormula.value, results = resultFormula.value
    let obj = formulaArrayToString(process, results)
    let deviationRangeText = rangeToString(deviationRangeObj.value, obj.eleMap)
    obj.eleMap.deviationRangeJson = JSON.stringify(deviationRangeObj.value)
    //特殊公式会有number
    let number = findNumber(process) || findNumber(results)
    //发起请求
    const { eleId, globalType, nodeId, pid } = getObjValue(dataInfo.value)
    const formData = {
        formula: obj.text,
        remark: '',
        nodeId: nodeId,
        elementId: eleId,
        scale: isRetain.value ? retainNum.value : '',
        number: number,
        map: JSON.stringify(obj.eleMap),
        scope: globalType,
        projectId: projectId.value || pid,
        dev: deviationRangeText,
    }
    let res = {}
    if (isNullES(formulaId.value)) {
        //新增
        res = await formulaApi.save({ ...formData, ver: 1 })
    } else {
        //更新
        res = await formulaApi.update({ id: formulaId.value, ...formData })
    }
    const { code, msg, data } = getObjValue(res)
    if (code !== 200) {
        submitLoading.value = false
        return
    }
    let msgStr = '保存成功'
    if (msg === '公式已删除') {
        formulaId.value = ''
        msgStr = msg
    } else if (!isNullES(data)) {
        formulaId.value = data
    }
    window?.$message.success(msgStr)
    await getFormulaStringToArrayApi()
    submitLoading.value = false
}

//关闭抽屉
const drawerClose = () => {
    const cardType = formulaCardType.value
    if (cardType === 'reset-fun') { //重置函数
        formulaCardType.value = 'project'
        isScrollBar.value = true
        curRangeFocusIndex.value = 0
        selectEleFormula.value = []
    } else if (cardType === 'range') {//允许偏差值范围
        formulaCardType.value = 'project'
        isRangeSelectEle.value = false
        curRangeFocusIndex.value = 0
        selectEleFormula3.value = []
        selectEleFormula4.value = []
        isScrollBar.value = true
    } else if (cardType === 'select-ele') { //多标签处理
        formulaCardType.value = 'project'
        equationSelectIndex.value = -1
        equationSelectEle.value = {}
        isScrollBar.value = true
    }
    //手写模式
    isHandWritEle.value = false
    handWritText.value = ''
    handWritEleMap.value = {}
    equationSelectEleCopy.value = {}
    isShow.value = false
    emit('close')
}
</script>

<style lang="scss">
@import '~src/styles/view/project/edit-formula';
</style>
