// - Create your context menu by instantiating ContextMenu and adding elements to it
// - Open your menu in response to a contextmenu event by using globalContextMenuSpace.openAtCursor(event, menu)

import { listen } from "rkgk/framework.js";

export class ContextMenu extends HTMLElement {
    connectedCallback() {
        this.classList.add("rkgk-panel");

        this.closeController = new AbortController();

        this.hasMouse = false;
        this.addEventListener("mouseover", () => (this.hasMouse = true));
        this.addEventListener("mouseleave", () => (this.hasMouse = false));

        window.addEventListener(
            "mousedown",
            () => {
                if (!this.hasMouse) {
                    this.close();
                }
            },
            { signal: this.closeController.signal },
        );

        window.addEventListener(
            "keydown",
            (event) => {
                if (event.key == "Escape") {
                    this.close();
                }
            },
            { signal: this.closeController.signal },
        );
    }

    disconnectedCallback() {
        this.closeController.abort();
    }

    close() {
        this.space.close(this);
    }

    addButton(label, options) {
        let { classList, disabled, tooltip, noCloseOnClick } = options ?? {};
        classList ??= [];
        disabled ??= false;
        tooltip ??= "";
        noCloseOnClick ??= false;

        let button = this.appendChild(document.createElement("button"));
        button.classList.add(...classList);
        button.innerText = label;
        button.disabled = disabled;
        button.title = tooltip;

        button.addEventListener("click", () => {
            if (!noCloseOnClick) this.close();
        });

        return button;
    }

    addHtmlP(text, options) {
        let { classList } = options ?? {};
        classList ??= [];

        let p = this.appendChild(document.createElement("p"));
        p.innerHTML = text;
        p.classList.add(...classList);
        return p;
    }

    addSeparator() {
        this.appendChild(document.createElement("hr"));
    }
}

customElements.define("rkgk-context-menu", ContextMenu);

export class ContextMenuSpace extends HTMLElement {
    open(contextMenu) {
        contextMenu.space = this;
        this.appendChild(contextMenu);
    }

    close(contextMenu) {
        this.removeChild(contextMenu);
    }

    openAtCursor(cursorEvent, contextMenu) {
        this.open(contextMenu);

        // NOTE: This assumes the context menu space is positioned at (0, 0) and spans the full page.

        let areaWidth = this.clientWidth;
        let areaHeight = this.clientHeight;
        let menuWidth = contextMenu.clientWidth;
        let menuHeight = contextMenu.clientHeight;

        let x = cursorEvent.clientX;
        let y = cursorEvent.clientY;

        // If the menu would reach outside the screen bounds, snap it back in.
        if (x + menuWidth > areaWidth) x -= menuWidth;
        if (y + menuHeight > areaHeight) y -= menuHeight;

        contextMenu.style.transform = `translate(${x}px, ${y}px)`;
    }
}

customElements.define("rkgk-context-menu-space", ContextMenuSpace);

export const globalContextMenuSpace = document.querySelector("rkgk-context-menu-space");
