<template>
    <el-form-item label="起始节点（可修改）">
        <el-select class="input-attr"
                   v-model="data.fromFlowNodeId"
                   @change="methods.changeLinkFlowNodeIds('0')"
                   filterable clearable>
            <el-option
                    v-for="(item, index) in data.fromFlowNodeIds"
                    :key="item.id"
                    :label="item.nodeName"
                    :value="item.id">
            </el-option>
        </el-select>
    </el-form-item>
    <el-form-item label="目标节点（可修改）">
        <el-select class="input-attr"
                   v-model="data.toFlowNodeId"
                   @change="methods.changeLinkFlowNodeIds('1')"
                   filterable clearable>
            <el-option
                    v-for="(item, index) in data.toFlowNodeIds"
                    :key="item.id"
                    :label="item.nodeName"
                    :value="item.id">
            </el-option>
        </el-select>
    </el-form-item>

    <el-form-item label="条件组关系">
        <el-switch
                v-model="data.cond.groupsType" @change="methods.changeGroupsType"
                active-value="0"
                inactive-value="1"
                inactive-text="或"
                active-text="且">
        </el-switch>
    </el-form-item>
    
    <el-form-item label="条件模式">
        <el-radio-group @change="methods.handleCondValType" :disabled="data.existData"
                        v-model="data.cond.valType">
            <el-radio v-for="(item, index) in DIC_PROP.VAL_TYPE.slice(2, 6)" :key="index" :label="item.value"
                      style="width: 56px">
                {{ item.label }}
            </el-radio>
        </el-radio-group>
        <el-tooltip placement="top">
            <template #content>若无法切换模式，请先清空条件组列表</template>
            <el-icon style="margin-left: 30px">
                <QuestionFilled/>
            </el-icon>
        </el-tooltip>
    </el-form-item>

    <el-divider>组内条件配置</el-divider>

    <template v-if="data.cond.valType === '0'">
        <el-form-item label="组内条件关系">
            <el-switch
                    v-model="data.cond.groupType"
                    active-value="0"
                    inactive-value="1"
                    inactive-text="或"
                    active-text="且">
            </el-switch>
        </el-form-item>

        <el-table :data="data.cond.condGroup"
                  border style="width: 100%; margin-bottom: 10px" max-height="500">

            <el-table-column type="index" label="操作" width="80">
                <template #header>
                    <el-button icon="Plus" size="small" type="primary" circle @click="methods.onAddItem(true)"></el-button>
                </template>
                <template #default="scope">
                    <el-button icon="Minus" size="small" type="danger" circle @click="methods.handleCondDelete(scope.$index, scope.row)"></el-button>
                </template>
            </el-table-column>

            <el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" show-overflow-tooltip>
                <template #default="scope">
                    <el-select v-model="scope.row.varKeyVal" @change="methods.handleVarKeyVal(scope.row)"
                               clearable
                               filterable>
                        <el-option-group
                                v-for="(group, index) in data.allFieldPerms"
                                :key="index"
                                :label="group.label">
                            <el-option
                                    v-for="(item, index) in group.options"
                                    :disabled="item.prop.indexOf('_define_') !== -1"
                                    :key="index"
                                    :label="item.label"
                                    :value="item.prop">
                            </el-option>
                        </el-option-group>
                    </el-select>
                </template>
            </el-table-column>

            <el-table-column prop="operator" :label="t('flowClazz.operator')" show-overflow-tooltip>
                <template #default="scope">
                    <el-select v-model="scope.row.operator" @change="methods.handleVarKeyVal(scope.row)"
                               clearable>
                        <el-option
                                v-for="(item, index) in data.varValOperator"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value">
                        </el-option>
                    </el-select>
                </template>
            </el-table-column>

            <el-table-column prop="varVal" :label="t('flowClazz.varVal')" show-overflow-tooltip>
                <template #default="scope">
                    <el-input v-model="scope.row.varVal" clearable/>
                </template>
            </el-table-column>
        </el-table>
    </template>

    <el-form-item label="SpEL表达式" v-if="data.cond.valType === '1'">
        <el-input class="input-attr" v-model="data.cond.varKeyVal" placeholder="请输入SpEL表达式" clearable @blur="methods.handleCondVarKeyVal"/>
        <el-tooltip placement="top">
            <template #content>{{ PROP_CONST.TEXT_DESC.condSpELExplain }}</template>
            <el-icon style="margin-left: 10px">
                <QuestionFilled/>
            </el-icon>
        </el-tooltip>
    </el-form-item>

    <el-form-item label="函数表达式" v-if="data.cond.valType === '2'">
        <el-input class="input-attr" v-model="data.cond.varKeyVal" placeholder="请输入函数表达式" clearable @blur="methods.handleCondVarKeyVal"/>
        <el-tooltip placement="top">
            <template #content>{{ PROP_CONST.TEXT_DESC.condMethodExplain1 }}
                <br />{{ PROP_CONST.TEXT_DESC.condMethodExplain2 }}
                <br />{{ PROP_CONST.TEXT_DESC.condMethodExplain3 }}
                <br />{{ PROP_CONST.TEXT_DESC.condMethodExplain4 }}
            </template>
            <el-icon style="margin-left: 10px">
                <QuestionFilled/>
            </el-icon>
        </el-tooltip>
    </el-form-item>

    <div v-if="data.cond.valType === '2'" style="margin: 10px 13px">
        <span style="color: #409EFF;font-size: 14px">注: 当前函数表达式的返回值为字符串 1 ( 满足 ) 或 0 ( 不满足 )</span>
    </div>

    <template v-if="data.cond.valType === '3'">
        <el-form-item label="Http请求地址">
            <el-input class="input-attr" placeholder="可输入全路径或相对路径" v-model="data.cond.varKeyVal"
                      @blur="methods.handleCondVarKeyVal" clearable>
                <template #prepend>
                    <el-select v-model="data.cond.httpMethod">
                        <el-option v-for="(item, index) in DIC_PROP.HTTP_METHODS" :key="index" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                </template>
            </el-input>

            <el-tooltip content="点击可设置Http请求的参数信息" placement="bottom">
                <el-button type="primary" size="small" round style="margin-left: 10px"
                        @click="methods.openHttpUrlParams()">
                    {{ data.httpUrlParamsVisible ? '清空' : '参数' }}
                </el-button>
            </el-tooltip>
        </el-form-item>

        <flow-http-param ref="flowHttpParam" :currFlowForm="props.currFlowForm" :flowData="props.flowData"
                         :httpParam="props.currSelect.attributes.attrs.cdata.attrs"
                         :httpParamType="DIC_PROP.PARAM_RULE_TYPE[1].value"
                         v-if="data.httpUrlParamsVisible">
        </flow-http-param>
    </template>

    <template v-if="data.cond.valType === '0'">
        <el-button type="primary" round style="margin-left: 185px; margin-top: 30px; margin-bottom: 30px; width: 200px"
                   @click="methods.addFlowNodeCondGroup()">
            {{ data.oldCurrentRow ? '修改完成': '添加条件组' }}
        </el-button>
        <el-divider>已添加条件组列表(点击行可再次修改)</el-divider>
        <el-empty description="条件组列表为空" style="margin: 10px 230px" v-if="!data.existData">
        </el-empty>

        <template v-for="(item, index) in data.condGroups" v-else
                  :key="index">

            <el-collapse v-model="data.collapse">
                <el-collapse-item :name="index">
                    <template #title>
                        {{ '条件组 ' + (index + 1) }}

                        <el-icon style="margin-left: 10px" @click="methods.handleCondGroupDelete(index)">
                            <Delete />
                        </el-icon>
                    </template>

                    <el-form-item label="组内条件关系">
                        <el-switch
                                v-model="item.groupType" @change="methods.changeGroupType(item, index)"
                                active-value="0"
                                inactive-value="1"
                                inactive-text="或"
                                active-text="且">
                        </el-switch>
                    </el-form-item>

                    <el-table :data="item.condGroup" border style="width: 100%" max-height="500"
                              highlight-current-row @current-change="methods.handleCurrentChange" :ref="'tableDataRef' + index">

                        <el-table-column type="index" label="操作" width="80">
                            <template #default="scope">
                                <el-button icon="Minus" size="small" type="danger" circle
                                           @click="methods.handleSingleCondDelete(scope.$index, scope.row, index)"></el-button>
                            </template>
                        </el-table-column>
                        <el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" show-overflow-tooltip>
                            <template #default="scope">
                                <convert-group-name :options="data.allFieldPerms"
                                              :value="scope.row.varKeyVal"
                                              :valueKey="'prop'" :showKey="'label'"></convert-group-name>
                            </template>
                        </el-table-column>
                        <el-table-column prop="operator" :label="t('flowClazz.operator')" show-overflow-tooltip>
                            <template #default="scope">
                                <dict-tag :options="DIC_PROP.OPERATOR" :value="scope.row.operator"></dict-tag>
                            </template>
                        </el-table-column>
                        <el-table-column prop="varVal" :label="t('flowClazz.varVal')" show-overflow-tooltip/>
                    </el-table>
                </el-collapse-item>
            </el-collapse>
        </template>
    </template>
</template>

<script setup lang="ts" name="FlowConRule">
    import {useI18n} from "vue-i18n";
    import {useMessage} from "/@/hooks/message";
    import {rule, validateNull} from "/@/utils/validate";
    import {deepClone} from "/@/utils/other";
    import {DIC_PROP} from "/@/flow/support/dict-prop";
    import {buildSysFieldsFormOption} from "../../utils/form-perm";
    import {PROP_CONST} from "../../support/prop-const";
    import {changeLinkFlowNodeIds, handleLinkFlowNodeIds} from "./index";

    const {proxy} = getCurrentInstance();
    const FlowHttpParam = defineAsyncComponent(() => import('./flow-http-param.vue'));

    const {t} = useI18n();
    const $message = useMessage();
    const $emit = defineEmits(["hideAttrConfig"]);
    const props = defineProps({
        currFlowForm: {
            type: Object,
            default: null,
        },
        currSelect: {
            type: Object,
            default: null,
        },
        flowData: {
            type: Object,
            default: null,
        },
        attrConfigVisible: null
    });

    const condData = {
        httpMethod: 'GET',
        groupsType: '0',
        condGroup: [],
        groupType: '0',
        valType: '0',
        varKeyVal: null,
        operator: null,
        varVal: null,
    }

    const data = reactive({
        collapse: [0],
        allFieldPerms: [],
        formFieldPerms: [],
        cond: deepClone(condData),
        httpUrlParamsVisible: false,
        oldCurrentRow: null,
        condGroups: [],
        existData: false,
        modifyPointType: null,
        fromFlowNodeId: null,
        fromFlowNodeIds: [],
        toFlowNodeId: null,
        toFlowNodeIds: []
    })

    onMounted(() => {
        methods.changeTabPane(props.currSelect)
    })

    const methods = {
        openHttpUrlParams() {
            if (!data.cond.varKeyVal) {
                $message.warning("请先输入【Http请求地址】")
                return
            }
            if (data.httpUrlParamsVisible) {
                props.currSelect.attributes.attrs.cdata.attrs.httpParams = []
                data.httpUrlParamsVisible = false
            } else {
                data.httpUrlParamsVisible = true
            }
        },
        handleCurrentChange(row) {
            if (!row) return
            let condGroupsRow;
            for (let i = 0; i < data.condGroups.length; i++) {
                let index = data.condGroups[i].condGroup.indexOf(row);
                if (index !== -1) {
                    condGroupsRow = data.condGroups[i];
                }
            }
            // 先清空之前选中的其他条件组
            if (data.oldCurrentRow !== condGroupsRow) {
                let oldIndex = data.condGroups.indexOf(data.oldCurrentRow);
                if (oldIndex !== -1) {
                    proxy.$refs['tableDataRef' + oldIndex][0].setCurrentRow(null)
                }
            }
            data.cond = condGroupsRow
            data.oldCurrentRow = condGroupsRow
        },
        handleVarKeyVal(row) {
            let dots = row.varKeyVal.split('.').length - 1;
            if (dots === 2) {
                let find = DIC_PROP.OPERATOR.slice(6).find(f => f.value === row.operator);
                if (!find) {
                    $message.warning("子表单的字段只能选择包含或不包含")
                    row.operator = null
                }
            }
        },
        changeGroupsType(groupsType) {
            let condGroups = props.currSelect.attributes.attrs.cdata.attrs.condGroups;
            if (validateNull(condGroups)) return
            props.currSelect.attributes.attrs.cdata.attrs.condGroups.forEach(each => {
                each.groupsType = groupsType
            })
            methods.validateCondData()
        },
        changeGroupType(item, index) {
            let condGroups = props.currSelect.attributes.attrs.cdata.attrs.condGroups;
            if (validateNull(condGroups)) return
            props.currSelect.attributes.attrs.cdata.attrs.condGroups[index].groupType = item.groupType
            methods.validateCondData()
        },
        onAddItem(isAdd) {
            if (validateNull(data.formFieldPerms)) {
                buildSysFieldsFormOption(data, props, $message)
            }
            if (data.cond.condGroup.length > 0) {
                let find = data.cond.condGroup.find(f => !f.varKeyVal || !f.operator || !f.varVal);
                if (find) {
                    let b = !find.varKeyVal || !find.operator || !find.varVal;
                    if (isAdd && b) {
                        $message.warning("请先填写 表单字段 或 运算符 或 值")
                        return
                    }
                }
                if (!isAdd) data.cond.condGroup.splice(0, data.cond.condGroup.length);
            }
            let obj = {varKeyVal: '', operator: '', varVal: ''};
            data.cond.condGroup.push(obj);
        },
        addFlowNodeCondGroup() {
            if (validateNull(data.cond.condGroup)) {
                $message.warning("请先添加组内条件")
                return
            }
            let valType = data.cond.valType;
            let find = data.cond.condGroup.find(f => !f.varKeyVal || !f.operator || !f.varVal);
            if (find) {
                if (valType === DIC_PROP.VAL_TYPE[2].value) {
                    if (!find.varKeyVal || !find.operator || !find.varVal) {
                        $message.warning("表单字段 或 运算符 或 值 不能为空")
                        return
                    }
                }
            }
            if (data.oldCurrentRow) {
                // 先清空之前选中
                let index = data.condGroups.indexOf(data.cond);
                if (index !== -1) {
                    proxy.$refs['tableDataRef' + index][0].setCurrentRow(null)
                }
                data.oldCurrentRow = null
                data.cond = deepClone(condData);
            } else {
                let cond = deepClone(data.cond);
                props.currSelect.attributes.attrs.cdata.attrs.condGroups.unshift(cond)
                methods.validateCondData()
                methods.updateCondVarKeyVal(true)
            }
        },
        handleCondGroupDelete(index: number) {
            props.currSelect.attributes.attrs.cdata.attrs.condGroups.splice(index, 1)
            methods.validateCondData()
        },
        handleSingleCondDelete(index: number, row: any, groupIndex) {
            props.currSelect.attributes.attrs.cdata.attrs.condGroups[groupIndex].condGroup.splice(index, 1)
            if (validateNull(props.currSelect.attributes.attrs.cdata.attrs.condGroups[groupIndex].condGroup)) {
                methods.handleCondGroupDelete(groupIndex)
            }
            methods.validateCondData()
        },
        handleCondDelete(index: number, row: any) {
            data.cond.condGroup.splice(index, 1)
        },
        handleCondValType(type?) {
            if (type) {
                data.cond.varKeyVal = null
                methods.updateCondVarKeyVal(false)
            }
            if (!type) {
                type = methods.initCurrVarKeyVal()
            }
            if (type === DIC_PROP.VAL_TYPE[2].value) {
                data.varValOperator = DIC_PROP.OPERATOR
                methods.onAddItem(false)
            } else {
                data.varValOperator = []
            }
            data.cond.operator = null
            data.cond.varVal = null
        },
        handleCondVarKeyVal() {
            let val = data.cond.varKeyVal
            let valType = data.cond.valType;
            if (!val) {
                methods.updateCondVarKeyVal(false)
                return
            }
            if (valType === DIC_PROP.VAL_TYPE[2].value) return
            if (valType === DIC_PROP.VAL_TYPE[3].value && val.indexOf("#") === -1) {
                data.cond.varKeyVal = null
                $message.warning("当选择SpEL模式时, SpEL表达式必须符合SpEL格式")
                return;
            } else if (valType === DIC_PROP.VAL_TYPE[4].value && val.indexOf("#") === -1) {
                data.cond.varKeyVal = null
                $message.warning("当选择专业模式时, 函数表达式必须符合规定的格式")
                return;
            }
            methods.updateCondVarKeyVal(true)
        },
        updateCondVarKeyVal(isSave) {
            props.currSelect.attributes.attrs.cdata.attrs.valType = data.cond.valType
            if (isSave) {
                if (data.cond.valType === DIC_PROP.VAL_TYPE[2].value) {
                    props.currSelect.attributes.attrs.cdata.attrs.varKeyVal = PROP_CONST.VAR_KEY_VAL.link
                } else {
                    props.currSelect.attributes.attrs.cdata.attrs.varKeyVal = data.cond.varKeyVal
                }
                props.currSelect.attributes.attrs.cdata.attrs.httpMethod = data.cond.httpMethod
            } else {
                props.currSelect.attributes.attrs.cdata.attrs.varKeyVal = null
                props.currSelect.attributes.attrs.cdata.attrs.varKeyValName = null

                props.currSelect.attributes.attrs.cdata.attrs.condGroups = []

                props.currSelect.attributes.attrs.cdata.attrs.httpParams = []
                props.currSelect.attributes.attrs.cdata.attrs.httpMethod = null
                data.httpUrlParamsVisible = false
            }
        },
        validateCondData() {
            let condGroups = props.currSelect.attributes.attrs.cdata.attrs.condGroups;
            if (!condGroups) {
                props.currSelect.attributes.attrs.cdata.attrs.condGroups = []
            }
            data.condGroups.splice(0, data.condGroups.length);
            props.currSelect.attributes.attrs.cdata.attrs.condGroups.forEach(each => data.condGroups.push(each))
            data.existData = !validateNull(data.condGroups)
        },
        initCurrVarKeyVal() {
            data.cond.valType = props.currSelect.attributes.attrs.cdata.attrs.valType
            if (data.condGroups.length <= 0) {
                data.cond.varKeyVal = props.currSelect.attributes.attrs.cdata.attrs.varKeyVal
                let httpMethod = props.currSelect.attributes.attrs.cdata.attrs.httpMethod
                if (httpMethod) data.cond.httpMethod = httpMethod
            } else {
                data.cond.groupsType = data.condGroups[0].groupsType
            }
            let httpParams = props.currSelect.attributes.attrs.cdata.attrs.httpParams;
            if (!validateNull(httpParams)) {
                data.httpUrlParamsVisible = true
            }
            return data.cond.valType
        },
        handleLinkFlowNodeIds() {
            handleLinkFlowNodeIds(data, props)
        },
        changeLinkFlowNodeIds(type) {
            data.modifyPointType = type
            changeLinkFlowNodeIds(data, props, methods, $emit)
        },
        changeTabPane(val) {
            methods.validateCondData()
            methods.handleCondValType()
            methods.handleLinkFlowNodeIds()
        }
    }
    // 监听双向绑定
    watch(
        () => props.currSelect,
        (val) => {
            if (Object.keys(val).length === 0 || !props.attrConfigVisible) {
                return
            }
            methods.changeTabPane(val)
        }
    );

</script>

<style lang="scss">
  @import '../assets/style/flow-attr.scss';
</style>
