import {i18nRender} from '@/locales/index'
import {geometricObj} from '@/store/assets/fmeaTreeData'

/**
 * 数组转Tree
 * @param targetNode 目标节点
 * @param targetNode 目标节点
 * @returns {*[]}
 */
export function arrayToTree(targetNode, nodeArray) {
    targetNode = cleanNodeData([targetNode])[0];
    findChildren(targetNode, cleanNodeData(nodeArray), "");
    return [targetNode];
}

/**
 * 数值转Tree  根据leftNo排序
 * @param targetNode 目标节点
 * @param targetNode 目标节点
 * @returns {*[]}
 */
export function arrayToTreeCompare(targetNode, nodeArray) {
    targetNode = cleanNodeData([targetNode])[0];
    nodeArray = nodeArray.sort((nodeArrayO1, nodeArrayO2) => nodeArrayO1.leftNo - nodeArrayO2.leftNo)
    findChildren(targetNode, cleanNodeData(nodeArray), "");
    return [targetNode];
}

/**
 * 清洗节点数据
 * @param sourceArray 源数组
 * @param curOptTypeCode 当前优化类型标识位
 * @returns {*}
 */
function cleanNodeData(sourceArray, curOptTypeCode) {
    let array = sourceArray.map((item) => {
        return {
            id: item.id,
            pid: item.pid,
            name: replaceNullName(item),
            deep: item.deep,
            leftNo: item.leftNo,
            rightNo: item.rightNo,
            struTypeCode: item.struTypeCode,
            curOptTypeCode: curOptTypeCode,
            /** 评审意见 */
            reviewCommentsFlag: item.reviewCommentsFlag ? item.reviewCommentsFlag : item.hasStruComment,
            /** 附件标识 0：无，1：有 */
            annexFlag: item.annexFlag,
            /** 关联历史失效 */
            joinHistoryFaultFlag: item.joinHistoryFaultFlag ? item.joinHistoryFaultFlag : item.hasFmeaResearch,
            parentNet: item.parentNet ? item.parentNet : item.netParentCnt ? 1 : 0,
            childNet: item.childNet ? item.childNet : item.netChildCnt ? 1 : 0,
            prefix: item.prefix ? item.prefix
                : item.beginInfo ? item.beginInfo
                    : item.middleInfo ? item.middleInfo : '',
            /** 潜在关键特性名称 */
            keyFeatureName: item.keyFeatureName ? item.keyFeatureName : item.lname,
            suffix: item.suffix ? item.suffix : item.endInfo ? item.endInfo : '',
            children: [],
            chartFlag: (item.struTypeCode === '01' && item.connectId) ? 1 : item.chartFlag,
            // chartFlag: item.chartFlag,
            /** 连接ID */
            connectId: item.connectId,
            linkName: item.linkName ? item.linkName : '',
            sourceName: item.sourceName,
            targetName: item.targetName,
            funComplete: item.funComplete,
            failComplete: item.failComplete,
            reqComplete: item.reqComplete,
            sodComplete: item.sodComplete,
        }
    });
    return array.filter((item) => item != null);
    /*return array.filter((item) => item != null).sort((a, b) => {
        if (a.connectId) {
            return 1;
        } else {
            return -1;
        }
    });*/
}

/**
 * 填补空的名称
 * @param node 节点
 * @returns {*}
 */
export function replaceNullName(node) {
    let name = node.name;
    switch (node.struTypeCode) {
        case '14':
            name = i18nRender('global-dict.current-measures');
            break;
        case '07':
            name = i18nRender('global-dict.optimization-measures');
            break;
        case '08':
            name = node.name ? node.name : i18nRender('global-dict.group');
            break;
    }
    return name;
}

/**
 * 递归取得子集
 * curOptTypeCode参数：当前优化类型标识位
 * 1：区分当前措施组（1408）或优化预防措施（0708）
 * 2：区分当前预防措施（1409）或优化预防措施（0709）
 * 3：区分当前探测措施（1410）或优化探测措施（0710）
 * @param node 节点
 * @param nodeArray 节点数组
 * @param measureTypeCode 措施状态类型CODE：14、07
 * @returns {*}
 */
function findChildren(node, nodeArray, measureTypeCode) {
    for (let i = 0, len = nodeArray.length; i < len; i++) {
        if ("14,07".indexOf(nodeArray[i].struTypeCode) !== -1) {
            measureTypeCode = nodeArray[i].struTypeCode;
        }
        if ("08,09,10".indexOf(nodeArray[i].struTypeCode) !== -1) {
            nodeArray[i].curOptTypeCode = measureTypeCode + nodeArray[i].struTypeCode;
        }
        if (node.id === nodeArray[i].pid) {
            node.children.push(findChildren(nodeArray[i], nodeArray, measureTypeCode));
        }
    }
    return node;
}

/**
 * 过滤节点
 * @param treeNodeArray Tree节点数组
 * @param pid 父ID
 * @param filterTypeCode 过滤类型CODE
 * @param filterNodes 过滤节点数组
 * @param showNodeArray 显示节点数组
 */
export function filterNode(treeNodes, sourceNodes, pid, filterTypeCode, filterNodes, showNodes, historyShowHide) {
    for (let i = 0, len = treeNodes.length; i < len; i++) {
        let node = {};
        jQuery.extend(true, node, treeNodes[i]);
        node.pid = pid;
        // 判断是否显示关联历史失效
        if (historyShowHide) {
            // 结构和接口节点在右树不能被过滤掉 不管右树是否有关联历史问题的失效节点
            if ('01,99'.indexOf(node.struTypeCode) === -1 && (filterTypeCode.indexOf(node.struTypeCode) !== -1 || !node.historyFailure)) {
                if (node.children) filterNode(node.children, sourceNodes, node.pid, filterTypeCode, filterNodes, showNodes, historyShowHide);
            } else {
                showNodes.push(getNode(node.id, pid, sourceNodes));
                if (node.children) filterNode(node.children, sourceNodes, node.id, filterTypeCode, filterNodes, showNodes, historyShowHide);
            }
        } else {
            // 判断节点类型
            if ((filterTypeCode && filterTypeCode.indexOf(node.struTypeCode) !== -1) || filterNodes.indexOf(node.id) !== -1) {
                if (node.children) filterNode(node.children, sourceNodes, node.pid, filterTypeCode, filterNodes, showNodes, false);
            } else {
                showNodes.push(getNode(node.id, pid, sourceNodes));
                if (node.children) filterNode(node.children, sourceNodes, node.id, filterTypeCode, filterNodes, showNodes, false);
            }
        }

    }
}

/**
 * 查询功能下的sod值是否完整
 * @param sourceNodes 功能节点
 */
export function inspectSODComplete(sourceNodes) {
    let sodSign = 0
    if (sourceNodes.struTypeCode === '08') {
        if (sourceNodes.prefix.includes('S(max)?') || sourceNodes.prefix.includes('S(max)=?') ||
            sourceNodes.prefix.includes('O?') || sourceNodes.prefix.includes('O=?') ||
            sourceNodes.prefix.includes('D?') || sourceNodes.prefix.includes('D=?')){//存在sod缺失的措施组就返回1，其余情况返回0
            sodSign = 1
        }else {
            sodSign = 0
        }
    }else if (sourceNodes.children.length > 0){
        let sodIndex = 0
        for (let i = 0, len = sourceNodes.children.length; i < len; i++){
            if (inspectSODComplete(sourceNodes.children[i]) === 1) ++sodIndex;
        }
        if (sodIndex > 0){
            sodSign = 1
        }else {
            sodSign = 0
        }
    }else {
        sodSign = 0
    }
    return sodSign;
}

/**
 * 取节点
 * @param id
 * @param pid
 * @param sourceNodes
 * @returns {*}
 */
function getNode(id, pid, sourceNodes) {
    for (let i = 0, len = sourceNodes.length; i < len; i++) {
        let node = {};
        jQuery.extend(true, node, sourceNodes[i]);
        if (sourceNodes[i].id === id) {
            node.pid = pid;
            return node;
        }
    }
}

/**
 * 过滤网节点{功能网、失效网}
 * @param sourceNodes 节点数组
 * @param netType 连接方式
 * @param filterNetTypeCode 过滤网类型CODE
 */
export function filterNetNode(sourceNodes, netType, filterNetTypeCode) {
    let hideNodes = [];
    for (let i = 0, len = sourceNodes.length; i < len; i++) {
        let node = {};
        jQuery.extend(true, node, sourceNodes[i]);
        // 符合条件的节点，需隐藏
        if (isHideNet(node, netType) && filterNetTypeCode.indexOf(node.struTypeCode) !== -1) {
            hideNodes.push(node.id);
        }
        // 父节点被隐藏，子节点也跟随隐藏
        if (hideNodes && hideNodes.length > 0 && hideNodes.indexOf(node.pid) !== -1) {
            hideNodes.push(node.id);
        }
    }
    // 处理显示节点
    if (hideNodes && hideNodes.length > 0) {
        let showNodes = [];
        for (let i = 0, len = sourceNodes.length; i < len; i++) {
            let node = {};
            jQuery.extend(true, node, sourceNodes[i]);
            if (hideNodes.indexOf(node.id) === -1) {
                showNodes.push(node);
            }
        }
        return showNodes;
    }
    return sourceNodes;
}

/**
 * 取得顶部结构/接口，层级
 * @param treeNodeArray Tree节点数组
 * @param checkNode 选中节点
 * @param topStruct 顶部结构（01）/接口（99）
 * @returns {*}
 */
export function getTopStructDeep(treeNodeArray, checkNode, topStruct) {
    let topStructDeep;
    for (let i = 0, len = treeNodeArray.length; i < len; i++) {
        let node = treeNodeArray[i];
        if ("01,99".indexOf(node.struTypeCode) !== -1)
            topStruct = node;
        if (node.id === checkNode.id) return topStruct.deep;
        topStructDeep = getTopStructDeep(node.children, checkNode, topStruct);
        if (topStructDeep) break;
    }
    return topStructDeep;
}

/**
 * 完整性检查：判断当前节点是否要隐藏
 * @param node 节点
 * @param netType 连接type：{00、10,11、01,11、11}
 * @returns Boolean
 */
export function isHideNet(node, netType) {
    // 判断节点类型&&该节点的连接状态
    return netType.indexOf(getNetType(node.netParentCnt, node.netChildCnt)) > -1;
}

/**
 * 获取元素左右的连接方式
 * @param netParentCnt 网的上级有无标识
 * @param netChildCnt 网的下级有无标识
 * @returns netType 连接type：{00、10,11、01,11、11}
 */
export function getNetType(netParentCnt, netChildCnt) {
    // 设定连接type
    let netType = '00';
    if (netParentCnt > 0 && netChildCnt === 0) {
        // 仅左侧连接
        netType = '10,11';
    } else if (netParentCnt === 0 && netChildCnt > 0) {
        // 仅右侧连接
        netType = '01,11';
    } else if (netParentCnt > 0 && netChildCnt > 0) {
        // 左右均连接
        netType = '11';
    }
    return netType;
}

/**
 * 找出两个数组的差集
 * @param arr1
 * @param arr2
 * @return {any[]}
 */
export function getDiff(arr1, arr2) {
    let aSet = new Set(arr1);
    let bSet = new Set(arr2);
    return Array.from(
        new Set(arr1.concat(arr2).filter(v => aSet.has(v) && !bSet.has(v)))
    );
}


/**
 * 替换Verisurf字体，class
 * @param val
 * @returns {string|*}
 */
export function replaceVerisurfClass(val) {
    if (!val) return "";

    let keys = Object.keys(geometricObj);
    let findIndex = keys.findIndex(key => {
        return val.indexOf(key) !== -1;
    });
    let curKey = keys[findIndex];
    if (curKey && geometricObj[curKey]) {
        let curVal = geometricObj[curKey];
        val = val.replace(curKey, '<span class="' + curVal + '" style="font-family: Verisurf"></span>');
    }
    return val;
}

/**
 * 处理形位公差JSON字符串，转数组
 * @param geometric
 * @return {*[]}
 */
export function handleGeometricToArray(geometric) {
    if (!geometric) return;
    let arr = JSON.parse(geometric);
    let geometricArr = [];
    for (let i = 0, len = arr.length; i < len; i++) {
        let item = arr[i];
        let itemArr = [];
        if (item.symbol) {
            itemArr.push(item.symbol);
        }
        if (item.content) {
            itemArr.push(item.content);
        }
        if (item.datumChildren && item.datumChildren.length > 0) {
            for (let j = 0, len_j = item.datumChildren.length; j < len_j; j++) {
                let item_j = item.datumChildren[j];
                // 基准
                if (item_j.value) itemArr.push(item_j.value);
                // 后缀
                if (item_j.suffix) itemArr.push(item_j.suffix);
            }
        }
        geometricArr.push(itemArr);
    }
    return geometricArr;
}


/**
 * 处理形位公差JSON字符串，转字符串
 * @param geometric
 * @return {*[]}
 */
export function handleGeometricToStr(geometric) {
    if (!geometric) return '';
    let arr = JSON.parse(geometric);
    let geometricStr = '';
    for (let i = 0, len = arr.length; i < len; i++) {
        let item = arr[i];
        if (item.symbol) {
            geometricStr += ' ' + item.symbol;
        }
        if (item.content) {
            geometricStr += ' ' + item.content;
        }
        if (item.datumChildren && item.datumChildren.length > 0) {
            for (let j = 0, len_j = item.datumChildren.length; j < len_j; j++) {
                let item_j = item.datumChildren[j];
                // 基准
                if (item_j.value) geometricStr += ' ' + item_j.value;
                // 后缀
                if (item_j.suffix) geometricStr += ' ' + item_j.suffix;
            }
        }
    }
    return geometricStr;
}

