import * as Helpers from "../helpers";
import jQuery from "jquery";
import { createHTMLElement } from "../helpers";

export { NodeNeighborOverlay };

/**
 * Displays an overlay showing the neighbors of a node divided by the link type
 * that connects them.
 */
class NodeNeighborOverlay {
    constructor(graph, parentNode, infoOverlay, type = "link") {
        this.graph = graph;
        this.parentNode = parentNode;
        this.infoOverlay = infoOverlay;
        this.type = type;

        this.tabContentPages = {}; // Page content - links to other nodes
        this.tabNavHandles = {}; // Top-level handles of the content pages
    }

    /**
     * Creates the visible elements of the overlay.
     * Must be called after the graph has been initialized.
     */
    create() {
        const bottomContainerDiv = Helpers.createDiv(
            "bottom-container",
            this.parentNode
        );
        // Create the collapsible of the entire menu
        const coll = Helpers.createDiv("button", bottomContainerDiv);
        coll.className = "neighbor-collapsible-title";
        coll.innerText = "Verwandte Inhalte";
        coll.style.textAlign = "center";

        // Div that displays the information about all the chapters
        const contentTabs = Helpers.createDiv(
            "neighbor-content-tabs",
            bottomContainerDiv
        );
        this.contentTab = contentTabs;
        contentTabs.style.display = "flex";
        coll.addEventListener("click", function () {
            if (contentTabs.style.display === "flex") {
                jQuery(contentTabs).slideUp("fast");
            } else {
                jQuery(contentTabs).slideDown({
                    start: function () {
                        jQuery(this).css({
                            display: "flex",
                        });
                    },
                });
            }
        });

        const colors =
            this.type === "link"
                ? this.graph.edgeColors
                : this.graph.nodeColors;
        for (const [cls, color] of Object.entries(colors)) {
            this.createCollapsibleTab(contentTabs, cls, color);
        }
    }

    /**
     * Creates a new collapsible tab for a node with type name and a given color.
     * @param {HTMLElement} parent Parent of the new tab.
     * @param {string} name Name of the node type class
     * @param {string} color Color of the node type class
     */
    createCollapsibleTab(parent, name, color) {
        // Creating the collapsible tabs for the different chapters
        const collTab = Helpers.createDiv("button", parent);
        collTab.className = "neighbor-collapsible-section";
        collTab.innerText = name;
        collTab.type = name;
        this.tabNavHandles[name] = collTab;

        const collTabMarker = Helpers.createDiv(
            "neighbor-collapsible-marker-div",
            collTab
        );
        collTabMarker.style.borderColor = color;
        collTabMarker.style.backgroundColor = color;

        const openMarkerTabs = Helpers.createDiv(
            "neighbor-tab-open-status-marker",
            collTab
        );
        openMarkerTabs.innerText = "+";
        collTab.marker = openMarkerTabs;

        // Content of the different tabs
        const collTabContent = Helpers.createDiv(
            "neighbor-content-linksection",
            parent
        );
        collTabContent.type = name;

        const list = createHTMLElement("ul", collTabContent);
        list.style.margin = 0;
        collTabContent.list = list;

        this.tabContentPages[name] = collTabContent;
        collTabContent.marker = openMarkerTabs;
        collTab.addEventListener("click", function () {
            if (collTabContent.style.display === "flex") {
                jQuery(collTabContent).slideUp("fast");
                openMarkerTabs.innerText = "+";
            } else {
                jQuery(collTabContent).slideDown({
                    start: function () {
                        jQuery(this).css({ display: "flex" });
                    },
                });
                openMarkerTabs.innerText = "-";
            }
        });
    }

    /**
     * Clears the images from all tab content pages and makes the object
     * invisible.
     */
    clearTabContentPages() {
        for (const page of Object.values(this.tabContentPages)) {
            jQuery(page.list).empty();
            /*if(page.style.display === "flex") {
                page.style.display = "none";
            }*/
        }
    }

    /**
     * Creates a new image (with link) for the given target node.
     * @param target
     * @returns {HTMLDivElement}
     */
    createReference(target) {
        const linkDiv = document.createElement("li");
        var linkText = document.createTextNode(target.name);
        linkDiv.className = "neighbor-content-link";
        linkDiv.appendChild(linkText);
        jQuery(linkDiv).on("click", () => {
            this.graph.focusOnNode(target);
            this.infoOverlay.updateInfoOverlay(target);
        });
        return linkDiv;
    }

    /**
     * Updates all tabs to have content matching the given node.
     * @param node
     */
    updateTabs(node) {
        this.clearTabContentPages();
        for (const link of node.links) {
            const target = link.source == node ? link.target : link.source;
            const reference = this.createReference(target);
            if (this.type === "link") {
                this.tabContentPages[link.type].list.appendChild(reference);
            } else {
                this.tabContentPages[target.type].list.appendChild(reference);
            }
        }
        this.hideContentPages();
    }

    /**
     * Hides all the categories of a node that are not represented by a link
     * to another neighbor.
     */
    hideContentPages() {
        for (const page of Object.values(this.tabContentPages)) {
            if (!page.list.hasChildNodes()) {
                this.tabNavHandles[page.type].style.display = "none";
            } else {
                this.tabNavHandles[page.type].style.display = "flex";
                if (this.tabContentPages[page.type].style.display === "flex") {
                    this.tabNavHandles[page.type].marker.innerText = "-";
                } else {
                    this.tabNavHandles[page.type].marker.innerText = "+";
                }
            }
        }
    }

    /**
     * Toggle the visibility for a node type
     * @param {string} type The name of the type that should be toggled
     */
    toggleCategory(type) {
        const page = this.tabContentPages[type];
        if (this.tabNavHandles[page.type].style.display === "flex") {
            this.tabNavHandles[page.type].style.display = "none";
            const collTabContent = this.tabContentPages[page.type];
            jQuery(collTabContent).slideUp("fast");
            collTabContent.marker.innerText = "+";
        } else {
            if (page.list.hasChildNodes()) {
                this.tabNavHandles[page.type].style.display = "flex";
                if (this.tabContentPages[page.type].style.display === "flex") {
                    this.tabNavHandles[page.type].marker.innerText = "-";
                } else {
                    this.tabNavHandles[page.type].marker.innerText = "+";
                }
            }
        }
    }
}