var allPossiblePaths = []
this.onmessage = function (e) {

    if (e.data !== undefined) {


        if (e.data.functionName == "generatePDF") {
        //  Added by Pratik S on 03-May-2022 to add feature of light shade of Autprc path
            var customsvg = generatePDF(e.data.allParams.array, e.data.allParams.customSvg, e.data.allParams.linksColor)
            this.postMessage({ result: customsvg });

        } else if (e.data.functionName == "getAllPossiblePaths") {
            e.data.allParams.allPaths = removeUnwantedPaths(e.data.allParams.allPaths)
            getAllPossiblePaths(e.data.allParams.allPaths, e.data.allParams.initialNode, e.data.allParams.rootPath)
            this.postMessage({ result: allPossiblePaths });

        }
    }
}

// <START> Modified function by Pratik S on 02-May-2022 to handle QM_AutoProcessYN flag
function getReachableNodes(WFAllPaths, source) {

    if (source.Qm_Success_Queue == source.Qm_Fail_Queue && source.WB_Process_Success_Queue_ID == source.WB_Process_Fail_Queue_ID) {
        if (source.Qm_AutoProcessYN === 'Y') {
            return [
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Success_Queue })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })]
            ]
        } else {
            return [
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })]
            ]
        }
    }


    else if (source.Qm_Success_Queue != source.Qm_Fail_Queue && source.WB_Process_Success_Queue_ID == source.WB_Process_Fail_Queue_ID) {
        if (source.Qm_AutoProcessYN === 'Y') {
            return [
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Success_Queue })],
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Fail_Queue })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })]
            ]
        } else {
            return [
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })]
            ]
        }

    }


    else if (source.Qm_Success_Queue == source.Qm_Fail_Queue && source.WB_Process_Success_Queue_ID != source.WB_Process_Fail_Queue_ID) {
        if (source.Qm_AutoProcessYN === 'Y') {
            return [
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Success_Queue })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Fail_Queue_ID })]
            ]
        } else {
            return [

                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Fail_Queue_ID })]
            ]
        }

    } else {
        if (source.Qm_AutoProcessYN === 'Y') {
            return [
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Success_Queue })],
                ['Autprc', WFAllPaths.filter(obj => { return obj.QM_ID == source.Qm_Fail_Queue })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Fail_Queue_ID })]
            ]
        } else {
            return [
                
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Success_Queue_ID })],
                [source.WB_Caption, WFAllPaths.filter(obj => { return obj.QM_ID == source.WB_Process_Fail_Queue_ID })]
            ]
        }
    }



    
}
// <END> Modified function by Pratik S on 02-May-2022 to handle QM_AutoProcessYN flag

function getAllPossiblePaths(WFAllPaths, source, rootPath) {
    for (var i = 0; i < source[1].length; i++) {
        var pathList = []

        var elem = { ...source[1][i] }
        elem.PreviousAction = source[0]
        if (!rootPath.some(el => el.QM_ID == elem.QM_ID)) {
            rootPath.push(elem)
        }

                    
        var reachableNodes = getReachableNodes(WFAllPaths, elem)
        reachableNodes = reachableNodes.filter(obj => obj[1].length && obj[1][0].QM_ID !== elem.QM_ID)
        for (var j = 0; j < reachableNodes.length; j++) {
            pathList.push(rootPath)
            if (reachableNodes[j][1].length && rootPath.some(el => el.QM_ID == reachableNodes[j][1][0].QM_ID))
                continue
            getAllPossiblePaths(WFAllPaths, reachableNodes[j], rootPath)
            rootPath.pop()
        }
    }
    // Modified by Pratik S on 01-May-22 || Optimization (Unnecessary looping over objects)
    for (let i = rootPath.length; i > 1; i--) {
        var path = rootPath.slice(0, i)
        if (!arrayContainsObject(allPossiblePaths, path))
            allPossiblePaths.push(path)
        else
            break;
    }
}
function arrayContainsObject(array, element) {
    if (array.length > 0) {
        for (let i = 0; i < array.length; i++) {
            if (deepEqual(array[i], element))
                return true
        }
    }
    return false
}

function deepEqual(object1, object2) {
    const keys1 = Object.keys(object1);
    const keys2 = Object.keys(object2);
    if (keys1.length !== keys2.length) {
        return false;
    }
    for (const key of keys1) {
        const val1 = object1[key];
        const val2 = object2[key];
        const areObjects = isObject(val1) && isObject(val2);
        if (
            areObjects && !deepEqual(val1, val2) ||
            !areObjects && val1 !== val2
        ) {
            return false;
        }
    }
    return true;
}
function isObject(object) {
    return object != null && typeof object === 'object';
}

// Added by Pratik S -> INT1FIN47-49 --%>
// <START> Added by Pratik S on 03-May-2022 to add feature of light shade of Autprc path
function generatePDF(allPossiblePaths, customSvg, linksColor) {
        var queue_name = ''
        var init_X = 20
        var init_Y = 150       

        for (var i = 0; i < allPossiblePaths.length; i++) {
            var path = allPossiblePaths[i]
            for (var j = 0; j < path.length; j++) {
                var transform = '"translate(' + init_X + ', ' + init_Y + ')"'
                switch (path[j].QM_Queue_Status) {
                    case "Initial Queue":
                        customSvg = customSvg + '<circle r="6" fill="yellow" transform=' + transform + '></circle>'
                        queue_name = (i + 1) + ". " + path[j].QM_Name
                        break;
                    case "Intermediate Queue":
                        customSvg = customSvg + '<circle r="6" fill="gray" transform=' + transform + '></circle>'
                        queue_name = path[j].QM_Name
                        break;
                    case "Terminal Queue":
                        customSvg = customSvg + '<circle r="6" fill="#D3694D" transform=' + transform + '></circle>'
                        queue_name = path[j].QM_Name
                        break;
                }
                queue_name = queue_name.replace(
                    new RegExp(`(?![^\\n]{1,${20}}$)([^\\n]{1,${20}})\\s`, 'g'), '$1@'
                );
                if (j != path.length - 1) {
                    var d = "M" + init_X + "," + init_Y + "A0,0 0 0 1," + (init_X + 200) + "," + init_Y + "A0,0 0 0 0," + init_X + "," + init_Y + "M" + (init_X + 200 - 6) + "," + init_Y + "l-10,-3.5L" + (init_X + 200 - 16) + "," + (init_Y + 3.5) + "z"
                    if (path[j + 1].PreviousAction == "Autprc") {
                        customSvg = customSvg + '<path class="link links_movement" fill="' + pSBC(0.7, linksColor, false, true) + '" stroke="' + pSBC(0.7, linksColor, false, true) + ' " d="' + d + '"></path>'

                    } else {
                        customSvg = customSvg + '<path class="link links_movement" fill="' + linksColor + '" stroke="' + linksColor + ' " d="' + d + '"></path>'

                    }
                }

                //var linkdata = '<g transform=' + transform + '><text x="1" y="1.50em" class="filltextcolor"><tspan x="1" y="1.50em" dy="0em">' + queue_name + '</tspan></text><text x="-120" y="-0.50em" class="filltextcolor" style="font-size: 10px;"><tspan x="-120" y="-0.50em" dy="0em">' + path[j].PreviousAction + '</tspan></text></g>'
                var linkdata = '<g transform=' + transform + '><text x="1" y="1.50em" class="filltextcolor">'
                queue_name_list = queue_name.split("@")
                for (var k = 0; k < queue_name_list.length; k++) {
                    linkdata = linkdata + '<tspan x="1" y="1.50em" dy="' + (k) + 'em">' + queue_name_list[k] + '</tspan>'
                }
                linkdata = linkdata + '</text><text x="-120" y="-0.50em" class="filltextcolor" style="font-size: 12px;"><tspan x="-120" y="-0.50em" dy="0em">' + path[j].PreviousAction + '</tspan></text></g>'
                customSvg = customSvg + linkdata
                init_X = 20 + ((j + 1) * 200)
            }
            init_X = 20
            init_Y += 100
        }
        customSvg = customSvg + '</svg>'
        customSvg = customSvg.replace('id="titleText"', 'id="titleText" font-size="2em"');
        
        return customSvg
}
//<END>  Added by Pratik S on 03-May-2022 to add feature of light shade of Autprc path

	// Added by Pratik S on 29 Nov 2021  INT1FIN47-49 || END

// Modified by Pratik S on 01-May-22 || Optimization (Removing unwanted objects)
function removeUnwantedPaths(WFAllPaths) {
    
    
    var uniqueIDs = Object.values(
        WFAllPaths.reduce((WFAllPaths, obj) => ({ ...WFAllPaths, [obj.QM_ID]: obj.QM_ID }), {})
    );
    
    var newAllPaths = []
    for (var i = 0; i < uniqueIDs.length; i++) {
        var temp = WFAllPaths.filter(obj => obj.QM_ID == uniqueIDs[i])
        var nonZeroTarget = temp.filter(obj => obj.WB_Process_Success_Queue_ID != 0 || obj.WB_Process_Fail_Queue_ID != 0)
        if (nonZeroTarget.length == 0) {
            newAllPaths.push(temp[0])
        } else {
            for (var j = 0; j < nonZeroTarget.length; j++) {
                if (!arrayContainsObject(newAllPaths, nonZeroTarget[j]))
                    newAllPaths.push(nonZeroTarget[j])
            }
        }
    }
    uniqueIDs = Object.values(
        WFAllPaths.reduce((WFAllPaths, obj) => ({ ...WFAllPaths, [obj.QM_ID]: obj.QM_ID }), {})
    );
    
    return newAllPaths

}

// Added by Pratik S on 03-May-2022 to add feature of light shade of Autprc path

const pSBC = (p, c0, c1, l) => {
    let r, g, b, P, f, t, h, i = parseInt, m = Math.round, a = typeof (c1) == "string";
    if (typeof (p) != "number" || p < -1 || p > 1 || typeof (c0) != "string" || (c0[0] != 'r' && c0[0] != '#') || (c1 && !a)) return null;
    if (!this.pSBCr) this.pSBCr = (d) => {
        let n = d.length, x = {};
        if (n > 9) {
            [r, g, b, a] = d = d.split(","), n = d.length;
            if (n < 3 || n > 4) return null;
            x.r = i(r[3] == "a" ? r.slice(5) : r.slice(4)), x.g = i(g), x.b = i(b), x.a = a ? parseFloat(a) : -1
        } else {
            if (n == 8 || n == 6 || n < 4) return null;
            if (n < 6) d = "#" + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (n > 4 ? d[4] + d[4] : "");
            d = i(d.slice(1), 16);
            if (n == 9 || n == 5) x.r = d >> 24 & 255, x.g = d >> 16 & 255, x.b = d >> 8 & 255, x.a = m((d & 255) / 0.255) / 1000;
            else x.r = d >> 16, x.g = d >> 8 & 255, x.b = d & 255, x.a = -1
        } return x
    };
    h = c0.length > 9, h = a ? c1.length > 9 ? true : c1 == "c" ? !h : false : h, f = this.pSBCr(c0), P = p < 0, t = c1 && c1 != "c" ? this.pSBCr(c1) : P ? { r: 0, g: 0, b: 0, a: -1 } : { r: 255, g: 255, b: 255, a: -1 }, p = P ? p * -1 : p, P = 1 - p;
    if (!f || !t) return null;
    if (l) r = m(P * f.r + p * t.r), g = m(P * f.g + p * t.g), b = m(P * f.b + p * t.b);
    else r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5), g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5), b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5);
    a = f.a, t = t.a, f = a >= 0 || t >= 0, a = f ? a < 0 ? t : t < 0 ? a : a * P + t * p : 0;
    if (h) return "rgb" + (f ? "a(" : "(") + r + "," + g + "," + b + (f ? "," + m(a * 1000) / 1000 : "") + ")";
    else return "#" + (4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0)).toString(16).slice(1, f ? undefined : -2)
}