import {DIC_PROP} from "/@/flow/support/dict-prop";
import {PROP_CONST} from "/@/flow/support/prop-const";
import {CommonNodeType, HighNodeType} from "/@/flow/designer/config/type";
import {notifyLeft} from "/@/flow";
import {useMessageBox} from "/@/hooks/message";
import {validateNull} from "/@/utils/validate";
import {gateAttr, linkAttr, syncJobAttr, syncNodeAttr} from "/@/flow/designer/config/attr-config";
import {setPropsNullValue} from "/@/flow/support/common";
import {validateListFormOption} from "/@/flow/utils/form-perm";

/**
 * 常用工具类
 *
 * @author luolin
 */
// 反解析名称时未加载该常量
export function revParseWhoseLeaderName(data, dicData) {
    // 谁的主管，可自定义更多
    dicData.users.unshift(PROP_CONST.FLOW_METHOD.whoseLeader)
    if (!data.whoseLeader) return
    if (data.whoseLeader === PROP_CONST.FLOW_METHOD.whoseLeader.userId) {
        data.whoseLeaderName = PROP_CONST.FLOW_METHOD.whoseLeader.name
    } else {
        let find = dicData.users.find(f => f.userId === data.whoseLeader);
        if (find) data.whoseLeaderName = find.name;
    }
}

export async function revParseUserKeyValName(props, data, dicData, methods) {
    if (methods.validateCurrSelectDefJob) {
        if (!methods.validateCurrSelectDefJob()) return;
    }
    let valType = props.currSelect.attributes.attrs.cdata.defJob.valType;
    let userKeyVal = props.currSelect.attributes.attrs.cdata.defJob.userKeyVal;
    if (!userKeyVal) return;
    let userKeyValFrom;
    if (userKeyVal === PROP_CONST.VAR_KEY_VAL.order + 'createUser') {
        userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[0].value
        data.activeKey = 'flow-method'
    } else if (userKeyVal.indexOf('getUserDeptLeaderId') !== -1) {
        userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[1].value
        data.whoseLeader = userKeyVal.substring(userKeyVal.indexOf('(Long#') + 6, userKeyVal.indexOf(',Integer#'))
        data.leaderLevel = parseInt(userKeyVal.substring(userKeyVal.indexOf(',Integer#') + 9, userKeyVal.indexOf(',String#')))
        data.levelExtract = userKeyVal.substring(userKeyVal.indexOf(',String#') + 8, userKeyVal.indexOf(')'))
        data.activeKey = 'flow-method'
    } else if (userKeyVal.indexOf('listUserDeptMultiLeaderId') !== -1) {
        userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[2].value
        let lastIndex = userKeyVal.indexOf('String#') - 1;
        data.whoseLeader = userKeyVal.substring(userKeyVal.indexOf('(Long#') + 6, lastIndex)
        userKeyVal = userKeyVal.substr(lastIndex)
        lastIndex = userKeyVal.indexOf('Integer#') - 1;
        data.auditEndpoint = userKeyVal.substring(userKeyVal.indexOf('String#') + 7, lastIndex)
        userKeyVal = userKeyVal.substr(lastIndex)
        lastIndex = userKeyVal.indexOf('String#') - 1;
        let leaderLevel = userKeyVal.substring(userKeyVal.indexOf('Integer#') + 8, lastIndex)
        userKeyVal = userKeyVal.substr(lastIndex)
        if (data.auditEndpoint === '1') data.leaderLevel = parseInt(leaderLevel)
        lastIndex = userKeyVal.lastIndexOf('String#') - 1;
        data.seqAuditSort = userKeyVal.substring(userKeyVal.indexOf('String#') + 7, lastIndex)
        userKeyVal = userKeyVal.substr(lastIndex)
        data.levelExtract = userKeyVal.substring(userKeyVal.indexOf(')') - 1, userKeyVal.indexOf(')'))
        data.activeKey = 'flow-method'
    } else if (userKeyVal.indexOf('getDeptLeaderId') !== -1) {
        userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[3].value
        data.appointDeptId = userKeyVal.substring(userKeyVal.indexOf('(Long#') + 6, userKeyVal.indexOf(',String#'))
        data.levelExtract = userKeyVal.substring(userKeyVal.indexOf(',String#') + 8, userKeyVal.indexOf(')'))
    } else if (props.currSelect.attributes.attrs.cdata.defJob.userKeyValName) {
        let find = DIC_PROP.FLOW_METHOD_TYPE.find(f => f.label === props.currSelect.attributes.attrs.cdata.defJob.userKeyValName);
        // 再次编辑时优先显示为专业模式
        if (find) {
            userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[4].value
            data.userKeyVal = userKeyVal
            if (methods.handleUserKeyValFrom) methods.handleUserKeyValFrom(userKeyValFrom)
            data.activeKey = 'flow-method'
        }
    } else if (DIC_PROP.VAL_TYPE[4].value === valType && userKeyVal) {
        if (validateNull(data.formFieldPerms)) await validateListFormOption(data, props)
        if (!validateNull(data.formFieldPerms)) {
            let exist = data.formFieldPerms.find(f => f.prop === userKeyVal);
            if (exist) userKeyValFrom = DIC_PROP.FLOW_METHOD_TYPE[4].value
        }
    }
    if (userKeyValFrom) {
        data.userKeyValFrom = userKeyValFrom
    } else {
        data.activeKey = 'flow-rule'
    }
}

export function parseUserKeyValName(props, data, methods) {
    if (methods.validateCurrSelectDefJob) {
        if (!methods.validateCurrSelectDefJob()) return;
    }
    let userKeyVal;
    if (data.userKeyValFrom === '0') {
        userKeyVal = PROP_CONST.VAR_KEY_VAL.order + 'createUser'
    } else if (data.userKeyValFrom === '1') {
        userKeyVal = '#distActorServiceImpl.getUserDeptLeaderId(Long#'+ data.whoseLeader +',Integer#'+ data.leaderLevel +',String#'+ data.levelExtract +')'
    } else if (data.userKeyValFrom === '2') {
        let leaderLevel = 'NULL'
        if (data.auditEndpoint === '1') leaderLevel = data.leaderLevel
        let seqAuditSort = 'NULL'
        if (data.seqAuditSort) seqAuditSort = data.seqAuditSort
        userKeyVal = '#distActorServiceImpl.listUserDeptMultiLeaderId(Long#'+ data.whoseLeader +',String#'+ data.auditEndpoint +',Integer#'+ leaderLevel +',String#'+ seqAuditSort +',String#'+ data.levelExtract +')'
    } else if (data.userKeyValFrom === '3') {
        userKeyVal = '#distActorServiceImpl.getDeptLeaderId(Long#'+ data.appointDeptId +',String#'+ data.levelExtract +')'
    } else if (data.userKeyValFrom === '4') {
        userKeyVal = data.userKeyVal
    }
    if (data.userKeyValFrom === '1' || data.userKeyValFrom === '2') {
        if (!data.whoseLeader) {
            if (methods.$message) methods.$message('whoseLeader')
            return
        }
    }
    if (data.userKeyValFrom === '3') {
        if (!data.appointDeptId) {
            if (methods.$message) methods.$message('appointDeptId')
            return
        }
    }
    props.currSelect.attributes.attrs.cdata.defJob.userKeyVal = userKeyVal;
    props.currSelect.attributes.attrs.cdata.defJob.userKeyValName = DIC_PROP.FLOW_METHOD_TYPE.find(f => f.value === data.userKeyValFrom).label;

    props.currSelect.attributes.attrs.cdata.defJob.valType = DIC_PROP.VAL_TYPE[4].value
    // 清空其他参数
    props.currSelect.attributes.attrs.cdata.defJob.condGroups = []
    props.currSelect.attributes.attrs.cdata.defJob.httpParams = []
    props.currSelect.attributes.attrs.cdata.defJob.httpMethod = null
}

export function handleLinkFlowNodeIds(data, props) {
    data.toFlowNodeIds = []
    data.fromFlowNodeIds = []
    let models = window._jfGraph.getElements();
    data.fromFlowNodeId = props.currSelect.attributes.source.id
    data.toFlowNodeId = props.currSelect.attributes.target.id
    // 修正拖拽连线箭头更改目标节点
    props.currSelect.attributes.attrs.cdata.attrs.fromFlowNodeId = data.fromFlowNodeId
    props.currSelect.attributes.attrs.cdata.attrs.toFlowNodeId =  data.toFlowNodeId
    models.forEach(each => {
        if (!validateNodeType(each)) return
        let id = each.id
        let nodeName = each.attributes.attrs.label.text
        if (id !== props.currSelect.attributes.target.id) {
            data.fromFlowNodeIds.push({id, nodeName})
        }
        if (id !== props.currSelect.attributes.source.id) {
            data.toFlowNodeIds.push({id, nodeName})
        }
    })
}

export function changeLinkFlowNodeIds(data, props, methods?, $emit?) {
    useMessageBox()
        .confirm('是否确认修改连线的' + (data.modifyPointType === '0' ? '起点?' : '终点?'))
        .then(() => {
            doLinkFlowNodeIds(data, props, methods, $emit)
        })
}

function doLinkFlowNodeIds(data, props, methods?, $emit?) {
    if (data.modifyPointType === '0') {
        props.currSelect.attributes.attrs.cdata.attrs.fromFlowNodeId = data.fromFlowNodeId
        props.currSelect.set('source', { id: data.fromFlowNodeId });
    } else {
        props.currSelect.attributes.attrs.cdata.attrs.toFlowNodeId = data.toFlowNodeId
        props.currSelect.set('target', { id: data.toFlowNodeId });
    }
    if (methods) methods.handleLinkFlowNodeIds()
    if (window._flowConfig.globalConfig.isSimpleMode === '1') window._jfOperate.layout()
    else notifyLeft('专业模式不会自动调整连线轨迹，有必要时请手动调整', 'warning', 3000)
    if ($emit) $emit("hideAttrConfig", false, '1');
}

export function validateNodeType(currSelect, methods?, isVirtual?) {
    if (methods && !methods.validateCurrSelectAttrs()) return false;
    let type = currSelect.attributes.attrs.cdata.type;
    let noVirtual = type === CommonNodeType.START || type === CommonNodeType.END || type === CommonNodeType.SERIAL || type === CommonNodeType.PARALLEL;
    if (!isVirtual) return noVirtual
    return noVirtual || type === HighNodeType.VIRTUAL
}

export function handleSyncFlowNodeIds(data, props, methods) {
    data.syncFlowNodeIds = []
    if (!methods.validateCurrSelectAttrsAttrs()) return;
    props.currSelect.attributes.attrs.cdata.attrs.syncFlowNodeId = null
    let isGateway = props.currSelect.attributes.attrs.cdata.attrs.isGateway;
    let models = window._jfGraph.getElements();
    if (validateNull(models)) return
    models.forEach(each => {
        let cdata = each.attributes.attrs.cdata;
        let b = cdata.type === CommonNodeType.SERIAL || cdata.type === CommonNodeType.PARALLEL;
        if (b && props.currSelect.id !== each.id) {
            let id = each.id
            let nodeName = each.attributes.attrs.label.text + "（ID:" + id + "）"
            let isExist = false
            if (isGateway === '1') {
                if (cdata.attrs.isGateway === '1') isExist = true
            } else {
                if (cdata.attrs.isGateway !== '1') isExist = true
            }
            if (isExist) data.syncFlowNodeIds.push({id, nodeName})
        }
    })
}

export function changeSyncFlowNodeId(id, props, methods, $message) {
    let models = window._jfGraph.getElements();
    if (validateNull(models) || !id) return
    let isGateway = props.currSelect.attributes.attrs.cdata.attrs.isGateway;
    let cdata = models.find(f => f.id === id).attributes.attrs.cdata;
    let nodeAttrs: any[];
    if (isGateway !== '1') {
        nodeAttrs = Object.keys(syncNodeAttr);
        if (!validateNull(cdata.defJob)) {
            setPropsNullValue(props.currSelect.attributes.attrs.cdata.defJob, cdata.defJob, ...Object.keys(syncJobAttr))
        }
    } else {
        nodeAttrs = Object.keys(gateAttr);
    }
    setPropsNullValue(props.currSelect.attributes.attrs.cdata.attrs, cdata.attrs, ...nodeAttrs)
    $message.warning("已同步其他节点的配置，请重新打开查看")
    methods.hideAttrConfig(false, '1');
}

export function handleSyncFlowNodeRelIds(data, props, methods) {
    data.syncFlowNodeRelIds = []
    if (!methods.validateCurrSelectAttrsAttrs()) return;
    props.currSelect.attributes.attrs.cdata.attrs.syncFlowNodeRelId = null
    let links = window._jfGraph.getLinks();
    if (validateNull(links)) return
    links.forEach(each => {
        if (props.currSelect.id !== each.id) {
            let id = each.id
            let linkName = "ID:" + id
            let text = each.attributes.labels[0].attrs.text.text;
            if (text) linkName = text + "（ID:" + id + "）"
            data.syncFlowNodeRelIds.push({id, linkName})
        }
    })
}

export function changeSyncFlowNodeRelId(id, props, methods, $message) {
    let links = window._jfGraph.getLinks();
    if (validateNull(links) || !id) return
    let cdata = links.find(f => f.id === id).attributes.attrs.cdata;
    let linkAttrs = Object.keys(linkAttr);
    setPropsNullValue(props.currSelect.attributes.attrs.cdata.attrs, cdata.attrs, ...linkAttrs)
    $message.warning("已同步其他连线的配置，请重新打开查看")
    methods.hideAttrConfig(false, '1');
}
