<template>
    <el-form v-if="methods.validateNode(props.currSelect)"
            label-position="left" class="flow-config-attr" label-width="130px">

        <el-form-item label="全部只读或可编辑" prop="formPermType">
            <el-tooltip placement="top">
                <template #content>1、对当前节点表单的字段全部只读 或 全部可编辑。默认全部可编辑
                    <br/> 2、可在下方进一步约束权限，如这里选择全部只读，下方配置某些字段可编辑
                </template>
                <el-radio-group v-model="props.currSelect.attributes.attrs.cdata.attrs.formPermType">
                    <el-radio v-for="(item, index) in DIC_PROP.ALL_FORM_PERM_TYPE" :key="index" :label="item.value" style="width: 135px">
                        {{ item.label }}
                    </el-radio>
                </el-radio-group>
            </el-tooltip>

            <el-tooltip placement="top" v-if="props.currSelect.attributes.attrs.cdata.attrs.formPermType">
                <template #content>清空后可在下方单个字段配置权限或业务侧自行判断</template>
                <el-button text type="primary" icon="delete" @click="props.currSelect.attributes.attrs.cdata.attrs.formPermType = null">
                    清空
                </el-button>
            </el-tooltip>
        </el-form-item>

        <el-divider>请选择表单名称</el-divider>
        <el-form-item label="PC待办页面">
            <el-tooltip placement="top">
                <template #content>若下拉选项为空或没有期望的表单，请先在节点属性-PC待办页面选择</template>
                <el-select class="input-attr"
                           v-model="props.currSelect.attributes.attrs.cdata.attrs.formId"
                           @change="methods.changeNodeFormId"
                           clearable filterable placeholder="请选择节点属性-PC待办页面">
                    <template v-for="(item, index) in props.formIds">
                        <el-option
                                v-if="methods.filterNodeFormId(item)"
                                :key="index"
                                :label="item.formName+' V'+item.version"
                                :value="item.id">
                        </el-option>
                    </template>
                </el-select>
            </el-tooltip>
            <el-button @click="methods.addFormPermission" type="primary" round v-if="props.isShowAdd"
                       style="margin-left: 10px;">新增字段
            </el-button>
            <el-button @click="methods.resetFormPerm" type="primary" size="small" round v-if="!props.isShowAdd"
                       style="margin-left: 10px;">重置权限
            </el-button>
        </el-form-item>

        <el-divider>参与者可以操作表单字段权限</el-divider>
        <el-empty description="表单字段权限列表为空" style="margin: 10px 230px" v-if="validateNull(data.formFieldPerms)">
        </el-empty>
        <el-form-item v-for="(item, index) in data.formFieldPerms" v-else
                      :label="item.label"
                      :key="index">
            <el-input style="width: 131px; margin-right: 10px" v-model="item.label" v-if="props.isShowAdd"></el-input>
            <el-input style="width: 131px; margin-right: 10px" v-model="item.prop" v-if="props.isShowAdd"></el-input>
            <el-radio-group v-model="item.permType">
                <el-radio v-for="(item, index) in DIC_PROP.FORM_PERM_TYPE" :key="index"
                          :disabled="props.currSelect.attributes.attrs.cdata.attrs.formPermType === item.value"
                          :label="item.value" style="width: 86px">
                    {{ item.label }}
                </el-radio>
            </el-radio-group>
            <el-button @click.prevent="methods.removeFormPermission(item.prop)" type="primary" size="small" round>
                删除
            </el-button>
        </el-form-item>
    </el-form>
</template>

<script setup lang="ts" name="FlowFormPerm">
    import {useI18n} from "vue-i18n";
    import {useMessage} from "/@/hooks/message";
    import {validateNull} from "/@/utils/validate";
    import {parseWithFunctions, validateRunFlow} from "../../index";
    import {buildFieldPerms, handleFormFieldPerms} from "../../utils/form-perm";
    import {CommonNodeType, HighNodeType} from "../config/type";
    import {listFormOption} from "/@/api/jsonflow/form-option";
    import {DIC_PROP} from "../../support/dict-prop";
    import {deepClone} from "/@/utils/other";

    const { proxy } = getCurrentInstance();

    const {t} = useI18n();
    const $message = useMessage();
    const props = defineProps({
        currFlowForm: {
            type: Object,
            default: null,
        },
        currSelect: {
            type: Object,
            default: null,
        },
        flowData: {
            type: Object,
            default: null,
        },
        formIds: {
            type: Array,
            default: null,
        },
        isShowAdd: {
            type: Boolean,
            default: false,
        },
    });

    const data = reactive({
        formFieldPerms: [],
    })

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

    const methods = {
        validateCurrSelectAttrs(currSelect?) {
            if (!currSelect) currSelect = props.currSelect;
            if (validateNull(currSelect.attributes)) return false
            return true
        },
        validateNode(currSelect) {
            if (!methods.validateCurrSelectAttrs()) return false;
            let type = currSelect.attributes.attrs.cdata.type;
            return type === CommonNodeType.START || type === CommonNodeType.END || type === CommonNodeType.SERIAL || type === CommonNodeType.PARALLEL || type === HighNodeType.VIRTUAL
        },
        filterNodeFormId(item) {
            let pcTodoUrl = props.currSelect.attributes.attrs.cdata.attrs.pcTodoUrl
            if (!validateNull(pcTodoUrl)) {
                return pcTodoUrl.includes(item.id)
            } else return false
        },
        changeNodeFormId(value) {
            if (!methods.validateNode(props.currSelect)) return;
            if (!value) {
                methods.clearPermData()
                return
            }
            data.formFieldPerms = []
            let find = props.formIds.find(f => f.id === value);
            if (validateNull(find.formInfo)) {
                methods.handleFormFieldPerms(find)
            } else {
                let formInfo = parseWithFunctions(find.formInfo, true)
                buildFieldPerms(data.formFieldPerms, formInfo.widgetList);
            }
            methods.setNodeAttrsFormFieldPerms()
        },
        handleFormFieldPerms(find) {
            // 无需前缀
            let isReturn = handleFormFieldPerms(data, $message, find, '');
            if (isReturn) return
            if (find.isCurrForm === '1' && !validateNull(find.formFieldPerms)) {
                methods.buildCustomFormPerm(find.formFieldPerms)
                return;
            }
            // 已配置或全部字段
            methods.handleCustomFormPerm(find.id, null, props.flowData.attrs.id , props.currSelect.id)
        },
        initNodeFormId() {
            if (Object.keys(props.currSelect).length === 0) return
            if (!methods.validateNode(props.currSelect)) return;
            let formId = props.currSelect.attributes.attrs.cdata.attrs.formId;
            if (!formId) {
                methods.clearPermData()
                return
            }
            // formId必存在权限
            data.formFieldPerms = props.currSelect.attributes.attrs.cdata.attrs.formFieldPerms;
            methods.initAddFormPermission(formId)
        },
        async initAddFormPermission(formId) {
            let find = props.formIds.find(f => f.id === formId);
            if (!find) return
            let formFieldPerms = []
            if (find.type === DIC_PROP.FORM_TYPE[1].value) {
                if (find.isCurrForm === '1') {
                    formFieldPerms = find.formFieldPerms
                } else {
                    formFieldPerms = await methods.reqCustomFormPerm(formId, DIC_PROP.FORM_DATA_TYPE[0].value, null, null)
                }
            }
            if (find.type !== DIC_PROP.FORM_TYPE[1].value) {
                if (!validateNull(find.formInfo)) {
                    let formInfo = parseWithFunctions(find.formInfo, true)
                    buildFieldPerms(formFieldPerms, formInfo.widgetList);
                }
            }
            if (validateNull(formFieldPerms)) return
            formFieldPerms.forEach(each => {
                let index = data.formFieldPerms.findIndex(f => f.propId ? each.propId === f.propId : each.prop === f.prop);
                if (index !== -1) {
                    let exist = data.formFieldPerms[index]
                    data.formFieldPerms.splice(index, 1);
                    each.permType = exist.permType
                    data.formFieldPerms.splice(index, 0, each);
                    return
                }
                data.formFieldPerms.push(each)
            })
        },
        removeFormPermission(prop) {
            if (data.formFieldPerms.length === 0) return
            data.formFieldPerms = data.formFieldPerms.filter(f => f.prop !== prop)
            methods.setNodeAttrsFormFieldPerms()
        },
        setNodeAttrsFormFieldPerms() {
            // 相同引用
            props.currSelect.attributes.attrs.cdata.attrs.formFieldPerms = data.formFieldPerms
        },
        addFormPermission() {
            let formId = props.currSelect.attributes.attrs.cdata.attrs.formId;
            if (!formId) {
                $message.warning("请先选择表单名称")
                return
            }
            if (!data.formFieldPerms) data.formFieldPerms = []
            let number = data.formFieldPerms.length + 1;
            data.formFieldPerms.unshift({
                prop: 'propName' + number,
                label: '请输入字段名称'
            })
            methods.setNodeAttrsFormFieldPerms()
        },
        async reqCustomFormPerm(formId, type, defFlowId, flowNodeId) {
            if (!type) type = DIC_PROP.FORM_DATA_TYPE[1].value
            // 判断流程实例独立配置
            let flowInstId = validateRunFlow(props);
            let resp = await listFormOption({
                type: type, formType: DIC_PROP.FORM_TYPE[1].value, formId: formId,
                flowInstId: flowInstId, defFlowId: defFlowId, flowNodeId: flowNodeId
            }).catch(() => {
                $message.error("获取系统表单字段权限失败");
            })
            return resp.data
        },
        async handleCustomFormPerm(formId, type, defFlowId, flowNodeId) {
            let formFieldPerms = await methods.reqCustomFormPerm(formId, type, defFlowId, flowNodeId)
            methods.buildCustomFormPerm(formFieldPerms)
        },
        buildCustomFormPerm(formFieldPerms) {
            if (!validateNull(formFieldPerms)) {
                // 不影响表单设计信息
                data.formFieldPerms = deepClone(formFieldPerms)
                methods.setNodeAttrsFormFieldPerms()
            } else {
                methods.clearPermData()
                $message.warning("当前选择的系统表单无字段信息，请先在表单设计中录入")
            }
        },
        resetFormPerm(){
            let formId = props.currSelect.attributes.attrs.cdata.attrs.formId;
            if (!formId) {
                $message.warning("请先选择表单名称")
                return
            }
            methods.clearPermData()
            let find = props.formIds.find(f => f.id === formId);
            if (find.type === DIC_PROP.FORM_TYPE[1].value) {
                if (find.isCurrForm === '1' && !validateNull(find.formFieldPerms)) {
                    methods.buildCustomFormPerm(find.formFieldPerms)
                } else {
                    methods.handleCustomFormPerm(formId, DIC_PROP.FORM_DATA_TYPE[0].value, null, null)
                }
            } else {
                methods.changeNodeFormId(formId)
            }
        },
        clearPermData() {
            data.formFieldPerms = []
            delete props.currSelect.attributes.attrs.cdata.attrs.formFieldPerms
        },
        changeTabPane(val) {
            methods.initNodeFormId()
        }
    }
    // 监听双向绑定
    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>
