// retoor <retoor@molodetz.nl>

import { Http } from "./Http.js";
import "./devii/devii-avatar.js";
import "./devii/devii-terminal.js";

export class DeviiTerminal {
    constructor() {
        this.element = null;
        this.avatar = null;
        this.bindEscapeTrigger();
        this.bindDoubleClickTrigger();
        this.bindOpenTrigger();
        this.ready = this.init();
    }

    async init() {
        try {
            await Http.getJson("/devii/session");
        } catch (error) {
            return;
        }

        this.avatar = document.createElement("devii-avatar");
        this.avatar.id = "devii";
        this.avatar.setAttribute("character", "Clippy");
        document.body.appendChild(this.avatar);

        this.element = document.createElement("devii-terminal");
        this.element.setAttribute("avatar", "devii");
        document.body.appendChild(this.element);

        this.maybeAutoOpen();
    }

    bindOpenTrigger() {
        document.addEventListener("click", (event) => {
            const trigger = event.target.closest("[data-devii-open]");
            if (!trigger) return;
            event.preventDefault();
            this.open(trigger.dataset.deviiPrompt || "");
        });
    }

    maybeAutoOpen() {
        const stored = this.element && this.element.hasStoredState && this.element.hasStoredState();
        if (document.querySelector("[data-devii-autoopen]") && !stored) {
            this.open();
        }
    }

    bindEscapeTrigger() {
        document.addEventListener(
            "keydown",
            (event) => {
                if (event.key !== "Escape" || event.repeat) return;
                if (this._canTriggerOnEscape()) this.open();
            },
            true,
        );
    }

    bindDoubleClickTrigger() {
        document.addEventListener("dblclick", (event) => this._onDoubleClick(event));
    }

    _onDoubleClick(event) {
        const terminal = event.target.closest("container-terminal");
        if (terminal) {
            if (!this._isInteractive(event.target)) terminal.close();
            return;
        }
        const devii = event.target.closest("devii-terminal");
        if (devii) {
            if (this.element && this.element.state !== "closed" && !this._isInteractive(event.target)) {
                this.close();
            }
            return;
        }
        if (this._canOpenOnGesture()) this.open();
    }

    _isInteractive(target) {
        return !!target.closest("button, a, input, textarea, select");
    }

    _canTriggerOnEscape() {
        if (this.element && this.element.state !== "closed") return false;
        return this._canOpenOnGesture();
    }

    _canOpenOnGesture() {
        if (document.querySelector(".modal-overlay.visible")) return false;
        if (document.querySelector(".dialog-overlay.visible")) return false;
        if (document.querySelector(".context-menu.visible")) return false;
        const mobilePanel = document.getElementById("mobile-panel");
        if (mobilePanel && mobilePanel.classList.contains("open")) return false;
        const active = document.activeElement;
        if (active) {
            const editable = ["INPUT", "TEXTAREA", "SELECT"].includes(active.tagName);
            if (editable || active.isContentEditable) return false;
        }
        return true;
    }

    async open(prompt = "") {
        await this.ready;
        if (!this.element) return;
        this.element.open();
        if (prompt && typeof this.element.prefill === "function") this.element.prefill(prompt);
    }

    async close() {
        await this.ready;
        if (this.element) this.element.close();
    }

    async toggle() {
        await this.ready;
        if (this.element) this.element.toggle();
    }
}
