<template>
    <div>
        <el-form label-position="left" class="flow-config-attr" label-width="160px">

            <el-form-item label="监听类">
                <el-input class="input-attr" :placeholder="props.clazzPlaceholder" v-model="data.clazz.clazz" clearable></el-input>
            </el-form-item>
            <el-form-item label="Http请求地址">
                <el-input class="input-attr" placeholder="可输入全路径或相对路径" v-model="data.clazz.httpUrl"
                          @blur="methods.handleHttpUrlBlur" clearable>
                    <template #prepend>
                        <el-select v-model="data.clazz.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(true)">
                        参数
                    </el-button>
                </el-tooltip>
            </el-form-item>
            <el-form-item label="触发时机">
                <el-select class="input-attr"
                           v-model="data.clazz.methods" multiple
                           clearable placeholder="多个方法名称, 英文逗号分隔, 顺序从左到右">
                    <el-option
                            v-for="(item, index) in props.addType === '0' && props.currSelect.attributes.attrs.cdata.attrs.isAutoAudit === '1' ?
                            props.flowMethods.slice(3) : props.flowMethods"
                            :key="item.value"
                            :label="item.label"
                            :value="item.value">
                    </el-option>
                </el-select>
            </el-form-item>

            <el-divider v-if="!data.moreInter">
                <el-button type="primary" link @click="methods.showMoreSetting()"
                           style="margin-left: 10px; font-size: 14px">
                    {{ data.moreInter ? '隐藏更多' : '更多配置' }}
                </el-button>
            </el-divider>

            <template v-if="data.moreInter">
                <div style="margin: 10px 13px">
                    <span style="color: red;font-size: 14px">注: 监听事件允许设置生效条件，用于控制在某种条件下才会执行</span>
                </div>
                <el-form-item label="条件模式">
                    <el-radio-group style="width: 313px" @change="methods.handleClazzValType" :disabled="data.existData"
                                    v-model="data.clazz.valType">
                        <el-radio v-for="(item, index) in DIC_PROP.VAL_TYPE.slice(2, 5)" :key="index" :label="item.value" style="width: 75px">
                            {{ item.label }}
                        </el-radio>
                    </el-radio-group>
                    <el-tooltip placement="top">
                        <template #content>若无法切换模式，请先清空监听事件列表</template>
                        <el-icon><QuestionFilled /></el-icon>
                    </el-tooltip>
                </el-form-item>

                <el-table :data="data.tableFieldData" v-if="data.clazz.valType === '0'"
                          border style="width: 100%; margin-bottom: 10px" max-height="500">
                    <el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" show-overflow-tooltip>
                        <template #default="scope">
                            <el-select v-model="data.clazz.varKeyVal" @change="methods.handleVarKeyVal"
                                       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="data.clazz.operator"
                                       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="data.clazz.varVal" clearable/>
                        </template>
                    </el-table-column>
                </el-table>

                <el-form-item label="SpEL表达式" v-if="data.clazz.valType === '1'">
                    <el-input class="input-attr" v-model="data.clazz.varKeyVal" clearable @blur="methods.handleClazzVarKeyVal"/>
                    <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.clazz.valType === '2'">
                    <el-input class="input-attr" v-model="data.clazz.varKeyVal" placeholder="请输入函数表达式" clearable @blur="methods.handleClazzVarKeyVal"/>
                    <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>

                <el-form-item label="监听备注">
                    <el-input class="input-attr" type="textarea" v-model="data.clazz.remark"></el-input>
                </el-form-item>
                <el-form-item label="监听排序">
                    <el-input-number class="input-attr" v-model="data.clazz.sort" :min="1"></el-input-number>
                </el-form-item>

            </template>

            <el-button type="primary" round style="margin-left: 185px; margin-top: 30px; margin-bottom: 30px; width: 200px" @click="methods.addFlowNodeClazz(props.addType)">
                {{ data.clazz.isSelectedRow ? '修改完成': '添加事件' }}
            </el-button>
            <el-divider>已添加监听事件列表(点击行可再次修改)</el-divider>
            <el-empty description="监听事件列表为空" style="margin: 10px 230px" v-if="!data.existData">
            </el-empty>
            <el-table :data="data.tableData" border style="width: 100%" max-height="500" v-else
                      highlight-current-row @current-change="methods.handleCurrentChange" ref="tableDataRef">
                <el-table-column type="index" label="操作" width="55">
                    <template #default="scope">
                        <el-button icon="Minus" size="small" type="danger" circle @click="methods.handleClazzDelete(scope.$index, scope.row, props.addType)"></el-button>
                    </template>
                </el-table-column>
                <el-table-column prop="clazz" :label="t('flowClazz.clazz')" width="130" show-overflow-tooltip/>
                <el-table-column prop="httpUrl" :label="t('flowClazz.httpUrl')" width="130" show-overflow-tooltip>
                </el-table-column>
                <el-table-column prop="methods" label="触发时机" width="130" show-overflow-tooltip>
                    <template #default="scope">
                        <dict-tag :options="props.flowMethods" :value="scope.row.methods"></dict-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="varKeyVal" label="函数表达式" width="130" show-overflow-tooltip v-if="data.clazz.valType === '2'"/>
                <el-table-column prop="varKeyVal" label="SpEL表达式" width="130" show-overflow-tooltip v-if="data.clazz.valType === '1'"/>
                <el-table-column prop="varKeyVal" :label="t('flowClazz.varKeyVal')" width="130" show-overflow-tooltip v-if="data.clazz.valType === '0'">
                    <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')" width="100" show-overflow-tooltip v-if="data.clazz.valType === '0'">
                    <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')" width="100" show-overflow-tooltip v-if="data.clazz.valType === '0'"/>
                <el-table-column prop="remark" :label="t('flowClazz.remark')" width="70" show-overflow-tooltip/>
                <el-table-column prop="sort" :label="t('flowClazz.sort')" width="70" show-overflow-tooltip/>
            </el-table>
        </el-form>

        <el-drawer
                class="flow-attr-drawer"
                title="Http请求的参数信息"
                direction="rtl"
                append-to-body
                :size="630" v-if="data.httpUrlParamsVisible"
                v-model="data.httpUrlParamsVisible">
            <el-form label-position="left" class="flow-attr flow-param-attr" label-width="150px">
                <flow-http-param ref="flowHttpParam" :currFlowForm="props.currFlowForm" :httpParam="data.clazz"
                                 :flowData="props.flowData"></flow-http-param>
            </el-form>
        </el-drawer>
    </div>
</template>

<script setup lang="ts" name="FlowClazz">
    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";

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

    const {t} = useI18n();
    const $message = useMessage();
    const props = defineProps({
        currFlowForm: {
            type: Object,
            default: null,
        },
        currSelect: {
            type: Object,
            default: null,
        },
        flowData: {
            type: Object,
            default: null,
        },
        clazzPlaceholder: {
            type: String,
            default: '',
        },
        flowMethods: {
            type: Array,
            default: [],
        },
        addType: {
            type: String,
            default: '',
        }
    });

    const clazzData = {
        clazz: null,
        httpUrl: null,
        httpMethod: 'GET',
        httpParams: null,
        methods: null,
        valType: null,
        varKeyVal: null,
        operator: null,
        varVal: null,
        remark: null,
        sort: 1,
    }
    const data = reactive({
        tableFieldData: [],
        allFieldPerms: [],
        formFieldPerms: [],
        clazz: deepClone(clazzData),
        httpUrlParamsVisible: false,
        moreInter: false,
        existData: false,
        tableData: []
    })

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

    const methods = {
        openHttpUrlParams(bool) {
            if (!data.clazz.httpUrl) {
                $message.warning("请先输入【Http请求地址】")
                return
            }
            data.httpUrlParamsVisible = bool
        },
        handleHttpUrlBlur() {
            if (!data.clazz.httpUrl) {
                data.clazz.httpParams = []
                return;
            }
        },
        handleCurrentChange(row) {
            if (!row) return
            data.clazz = row
            data.clazz.isSelectedRow = true
        },
        handleVarKeyVal(varKeyVal) {
            let dots = varKeyVal.split('.').length - 1;
            if (dots === 2) {
                data.varValOperator = DIC_PROP.OPERATOR.slice(6)
            } else {
                data.varValOperator = DIC_PROP.OPERATOR
            }
        },
        onAddItem(){
            if (validateNull(data.formFieldPerms)) {
                buildSysFieldsFormOption(data, props, $message)
            }
            if (data.tableFieldData.length > 0) return
            let obj = {varKeyVal: '', operator: '', varVal: ''};
            data.tableFieldData.push(obj);
        },
        addFlowNodeClazz(type) {
            let clazzes = type === '0' ? props.currSelect.attributes.attrs.cdata.attrs.clazzes : props.flowData.attrs.clazzes;
            if (!data.clazz.clazz && !data.clazz.httpUrl) {
                $message.warning("请填写 监听类 或者 Http请求地址")
                return
            }
            if (validateNull(data.clazz.methods)) {
                $message.warning("触发时机不能为空")
                return
            }
            if (!validateNull(clazzes) && !data.clazz.isSelectedRow) {
                if (data.clazz.clazz) {
                    let b = methods.validateClazzHttpUrl(clazzes, 'clazz', '监听类');
                    if (b) return;
                } else {
                    let b = methods.validateClazzHttpUrl(clazzes, 'httpUrl', 'Http请求地址');
                    if (b) return;
                }
            }
            if (data.clazz.clazz && data.clazz.httpUrl) {
                $message.error("监听类 与 Http请求地址不能同时存在")
                return;
            }
            if (data.clazz.isSelectedRow) {
                data.clazz.isSelectedRow = false
                proxy.$refs.tableDataRef.setCurrentRow(null)
                data.clazz = deepClone(clazzData);
            } else {
                let clazz = deepClone(data.clazz);
                if (type === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes.unshift(clazz)
                else props.flowData.attrs.clazzes.unshift(clazz)
                methods.validateClazzData()
            }
        },
        validateClazzHttpUrl(clazzes, key, errMsg){
            let find = clazzes.find(f => f[key] === data.clazz[key]);
            if (find) {
                $message.warning("请勿重复添加 " + errMsg)
                return true
            }
            return false
        },
        handleClazzDelete(index: number, row: any, type: string){
            if (type === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes.splice(index, 1)
            else props.flowData.attrs.clazzes.splice(index, 1)
            methods.validateClazzData()
        },
        handleClazzValType(type?) {
            if (!type) {
                type = methods.initCurrVarKeyVal()
            }
            if (type === DIC_PROP.VAL_TYPE[2].value) {
                data.varValOperator = DIC_PROP.OPERATOR
                methods.onAddItem()
            } else {
                data.varValOperator = []
            }
            data.clazz.varKeyVal = null
            data.clazz.operator = null
            data.clazz.varVal = null
        },
        handleClazzVarKeyVal() {
            let val = data.clazz.varKeyVal
            if (!val) return
            let valType = data.clazz.valType;
            if (valType === DIC_PROP.VAL_TYPE[3].value && val.indexOf("#") === -1) {
                data.clazz.varKeyVal = null
                $message.warning("当选择SpEL模式时, SpEL表达式必须符合SpEL格式")
            } else if (valType === DIC_PROP.VAL_TYPE[4].value && val.indexOf("#") === -1) {
                data.clazz.varKeyVal = null
                $message.warning("当选择专业模式时, 函数表达式必须符合规定的格式")
            }
        },
        showMoreSetting() {
            data.moreInter = !data.moreInter
        },
        validateClazzData() {
            let clazzes = props.addType === '0' ? props.currSelect.attributes.attrs.cdata.attrs.clazzes : props.flowData.attrs.clazzes;
            if (!clazzes) {
                if (props.addType === '0') props.currSelect.attributes.attrs.cdata.attrs.clazzes = []
                else props.flowData.attrs.clazzes = []
            }
            data.tableData.splice(0, data.tableData.length);
            if (props.addType === '0') {
                props.currSelect.attributes.attrs.cdata.attrs.clazzes.forEach(each => data.tableData.push(each))
            } else {
                props.flowData.attrs.clazzes.forEach(each => data.tableData.push(each))
            }
            data.existData = !validateNull(data.tableData)
        },
        initCurrVarKeyVal() {
            if (data.tableData.length > 0) {
                data.clazz.valType = data.tableData[0].valType
            }
            data.clazz.methods = []
            return data.clazz.valType
        },
        changeTabPane(val) {
            methods.validateClazzData()
            methods.handleClazzValType()
        }
    }
    // 监听双向绑定
    watch(
        () => props.currSelect,
        (val) => {
            if (Object.keys(val).length === 0) {
                return
            }
            methods.changeTabPane(val)
        }
    );

</script>

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