// Eryn Wells <eryn@erynwells.me>

class RubySwitch extends HTMLElement {
    static controlSizeInPixels = 32;
    static thumbTransitionDuration = 0.1;

    static settings = [
        {
            id: "ruby-switch-none",
            value: "none",
            label: "あ"
        },
        {
            id: "ruby-switch-both",
            value: "both",
            label: "<ruby>あ<rt>a</rt></ruby>",
            default: true
        },
        {
            id: "ruby-switch-hidden",
            value: "hidden",
            label: "ab"
        },
    ];

    #root;
    #thumb;

    constructor() {
        super();

        this.#updateValue(RubySwitch.settings.find(obj => obj.default).value);
        this.addEventListener("RubyStyleChanged", event => {
            this.#updateValue(event.detail.style);
        });

        this.#root = this.attachShadow({ mode: "closed" });
        this.#buildShadowDOM();

        this.#updateThumbPosition(this.#root.querySelector(".control[data-default]"));
    }

    #updateValue(style) {
        this.setAttribute("value", style);
    }

    get #stylesheet() {
        const controlSize = RubySwitch.controlSizeInPixels;
        const halfControlSize = controlSize / 2;

        return `
            #ruby-controls {
                box-sizing: border-box;
                display: inline-block;
                position: relative;
            }

            #controls {
                border: none;
                box-sizing: border-box;
                display: inline grid;
                grid-template-columns: repeat(3, ${controlSize}px);
                margin: 0;
                overflow: none;
                padding: 0;
            }

            #thumb {
                box-sizing: border-box;
                box-shadow: 2px 2px 6px #ccc;
                border: 0.5px solid #aaa;
                border-radius: ${halfControlSize}px;
                position: absolute;
                top: 0;
                height: ${controlSize}px;
                width: ${controlSize}px;
                z-index: 50;
                transition: left ${RubySwitch.thumbTransitionDuration}s;
            }

            .control {
                aspect-ratio: 1;
                display: flex;
                justify-content: center;
                align-items: center;
                height: ${controlSize}px;
                width: ${controlSize}px;
            }

            b {
                font-weight: normal;
                cursor: pointer;
            }

            label {
                z-index: 2;
                text-align: center;
            }

            #ruby-switch-both {
            }
        `;
    }

    #buildShadowDOM() {
        const root = this.#root;

        const style = document.createElement("style");
        style.textContent = this.#stylesheet;
        root.appendChild(style);

        let container = document.createElement("div");
        container.id = "ruby-controls";
        root.appendChild(container);

        let controls = document.createElement("div");
        controls.id = "controls";
        container.appendChild(controls);

        for (const desc of RubySwitch.settings) {
            let control = document.createElement("div");
            control.classList.add("control")
            control.id = desc.id;

            control.dataset.value = desc.value;
            if (desc.default) {
                control.dataset.default = "";
            }

            controls.appendChild(control);

            control.addEventListener("click", event => {
                event.stopPropagation();
                event.preventDefault();

                this.#updateThumbPosition(event.currentTarget);

                this.#root.dispatchEvent(new CustomEvent("RubyStyleChanged", {
                    bubbles: true,
                    composed: true,
                    detail: {
                        style: control.dataset.value,
                    },
                }));
            }, { capture: true });

            const label = document.createElement("b");
            label.innerHTML = desc.label;
            control.appendChild(label);
        }

        const thumb = document.createElement("div");
        this.#thumb = thumb;
        thumb.id = "thumb";
        container.appendChild(thumb);
    }

    #updateThumbPosition(selectedControl) {
        const controls = this.#root.querySelector("#controls");

        const trackBoundingRect = controls.getBoundingClientRect();
        const controlBoundingRect = selectedControl.getBoundingClientRect();

        const offset = controlBoundingRect.left - trackBoundingRect.left;
        this.#thumb.style.left = `${offset}px`;
    }
}

customElements.define("ruby-switch", RubySwitch);
