{% load i18n %}

<script>
    loadNetJsonGraph = (el='body', url='{{ graph_url }}?include_unpublished=true') => {
        const history_url = '{{ history_url }}?include_unpublished=true';
        const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const wsUrl = `${wsProtocol}//${window.location.host}/ws/network-topology/topology/${getTopologyIdFromUrl()}/`;
        const socket = new WebSocket(wsUrl);

        const getDataParseOptions = (data) => {
            return {
                dateString: data,
                parseRegular:
                    /^([1-9]\d{3})-(\d{1,2})-(\d{1,2})T(\d{1,2}):(\d{1,2}):(\d{1,2})(?:\.(\d{1,6}))?Z$/,
            };
        };
        const graphConfig = {
            series:{
                zoom:'2',
            },
            baseOptions: {
                backgroundColor: '#282222b3',
                toolbox: {
                    right: '60',
                    top: '15',
                },
            },
        }
        // load graph
        const graph = new NetJSONGraph(url, {
            el: el,
            graphConfig: graphConfig,
            linkCategories: [
                {
                    name: 'down',
                    linkStyle: {
                        color: '#c92517',
                        width: 6,
                    },
                    emphasis: {
                        linkStyle: {
                            color: '#FD0101',
                            opacity: 1,
                        },
                    },
                },
                {
                    name: 'up',
                    linkStyle: {
                        color: '#1ba619',
                        width: 6,
                    },
                    emphasis: {
                        linkStyle: {
                            color: '#3acc38',
                            opacity: 1,
                        },
                    },
                },
            ],
            prepareData: (data) => {
                data.links.map((link) => {
                    link.properties = link.properties || {};
                    if (link.properties.status) {
                        link.category = link.properties.status;
                    }
                    if (link.properties.created) {
                        link.properties.created = graph.utils.dateParse(
                            getDataParseOptions(link.properties.created)
                        );
                    }
                    if (link.properties.modified) {
                        link.properties.modified = graph.utils.dateParse(
                            getDataParseOptions(link.properties.modified)
                        );
                    }
                    if (link.properties.status_changed) {
                        link.properties.status_changed = graph.utils.dateParse(
                            getDataParseOptions(link.properties.status_changed)
                        );
                    }
                });

                data.nodes.map((node) => {
                    node.properties = node.properties || {};
                    if (node.properties.created) {
                        node.properties.created = graph.utils.dateParse(
                            getDataParseOptions(node.properties.created)
                        );
                    }
                    if (node.properties.modified) {
                        node.properties.modified = graph.utils.dateParse(
                            getDataParseOptions(node.properties.modified)
                        );
                    }
                });
                // Disable animation in graph for large topologies.
                // See https://github.com/openwisp/openwisp-network-topology/issues/164
                if (data.nodes.length > 20) {
                    graph.config.graphConfig.series.force = {
                        layoutAnimation: false,
                    };
                    graph.config.graphConfig.series.draggable = false;
                    if (data.nodes.length > 50) {
                        graph.config.graphConfig.series.force.edgeLength = 250;
                    }
                }
            },

            onLoad: () => {
                const gui = graph.utils.getGUI(graph);
                gui.init();
                if (graph.config.metadata) {
                    gui.createAboutContainer(graph);
                    gui.sideBar.classList.add("hidden");
                    graph.utils.updateMetadata.call(graph);
                }

                graph.config.onClickElement = (type, data) => {
                    switcher.classList.add('open');
                    let nodeLinkData;
                    if (type === 'node') {
                        nodeLinkData = graph.utils.nodeInfo(data);
                    } else {
                        nodeLinkData = graph.utils.linkInfo(data);
                    }
                    gui.getNodeLinkInfo(type, nodeLinkData);
                    gui.sideBar.classList.remove('hidden');
                };

                document.querySelector('.sideBarHandle').addEventListener('click', () => {
                    switcher.classList.toggle('open');
                });

                graph.utils.hideLoading();
            },
        });

        const overlay = document.querySelector(el);
        const createLegend = (key, name) => {
            const legendItem = document.createElement('p');
            const legendIcon = document.createElement('span');

            legendIcon.setAttribute('class', name);

            legend.appendChild(legendItem);
            legendItem.appendChild(legendIcon);

            legendItem.innerHTML += key;
            return legendItem;
        };
        const legend = document.createElement('div');
        const legendHeader = document.createElement('h4');
        legend.setAttribute('id', 'legend');
        legendHeader.innerHTML = 'Legend';
        legend.appendChild(legendHeader);
        legend.appendChild(createLegend('Up', 'link-up'));
        legend.appendChild(createLegend('Down', 'link-down'));
        overlay.appendChild(legend);

        const switcher = document.createElement('div');
        switcher.setAttribute('class', 'njg-switcher');
        const dateLabel = document.createElement('label');
        dateLabel.setAttribute('for', 'njg-datepicker');
        dateLabel.innerHTML = 'Date:';
        switcher.appendChild(dateLabel);
        const datePicker = document.createElement('input');
        datePicker.setAttribute('type', 'text');
        datePicker.setAttribute('id', 'njg-datepicker');
        datePicker.setAttribute('data-history-api', history_url);
        switcher.appendChild(datePicker);
        overlay.appendChild(switcher);

        socket.onmessage=function(e){
            const data=JSON.parse(e.data);
            if(data.type==="broadcast_topology"){
                const topology=JSON.parse(data.topology);
                window.graph.utils.JSONDataUpdate.call(window.graph, topology);
            }
        }

        graph.render();
        window.initTopologyHistory(django.jQuery);
        return graph

        // Utility function
        function getTopologyIdFromUrl() {
            let topologyId;
            try {
                topologyId = /\/((\w{4,12}-?)){5}\//.exec(window.location)[0];
            } catch (error) {
                try {
                    topologyId = /\/(\d+)\//.exec(window.location)[0];
                } catch (error) {
                    throw error;
                }
            }
            return topologyId.replace(/\//g, '');
        }
    };

</script>
