// retoor <retoor@molodetz.nl>

import { OptimisticAction } from "./OptimisticAction.js";

export class ReactionBar extends OptimisticAction {
    constructor() {
        super();
        document.addEventListener("click", (event) => this.onClick(event));
    }

    async onClick(event) {
        const addButton = event.target.closest(".reaction-add-btn");
        if (addButton) {
            event.preventDefault();
            this.togglePalette(addButton);
            return;
        }
        const trigger = event.target.closest("[data-reaction-emoji]");
        if (trigger && !trigger.disabled) {
            event.preventDefault();
            await this.react(trigger);
            return;
        }
        this.closeAllPalettes();
    }

    togglePalette(addButton) {
        const palette = addButton.parentElement.querySelector(".reaction-palette");
        const isOpen = palette.hidden === false;
        this.closeAllPalettes();
        palette.hidden = isOpen;
        if (!palette.hidden) {
            this.clampToViewport(palette);
            this.ensureInView(palette);
        }
    }

    clampToViewport(palette) {
        const margin = 8;
        palette.style.left = "";
        const rect = palette.getBoundingClientRect();
        const overflowRight = rect.right - (window.innerWidth - margin);
        if (overflowRight > 0) {
            palette.style.left = `${-overflowRight}px`;
        }
        const adjusted = palette.getBoundingClientRect();
        if (adjusted.left < margin) {
            const current = parseFloat(palette.style.left || "0");
            palette.style.left = `${current + (margin - adjusted.left)}px`;
        }
    }

    ensureInView(palette) {
        const margin = 8;
        const rect = palette.getBoundingClientRect();
        const extra = rect.height * 0.3;
        if (rect.top < margin) {
            window.scrollBy({ top: rect.top - margin - extra, behavior: "smooth" });
        } else if (rect.bottom > window.innerHeight - margin) {
            window.scrollBy({ top: rect.bottom - (window.innerHeight - margin) + extra, behavior: "smooth" });
        }
    }

    closeAllPalettes() {
        document.querySelectorAll(".reaction-palette").forEach((palette) => {
            palette.hidden = true;
        });
    }

    async react(trigger) {
        const bar = trigger.closest(".reaction-bar");
        if (!bar) {
            return;
        }
        const type = bar.dataset.reactionType;
        const uid = bar.dataset.reactionUid;
        const emoji = trigger.dataset.reactionEmoji;
        await this.submit(`/reactions/${type}/${uid}`, { emoji }, null, (result) => this.render(bar, result));
        this.closeAllPalettes();
    }

    render(bar, result) {
        const counts = result.counts || {};
        const mine = new Set(result.mine || []);
        bar.querySelectorAll(".reaction-list .reaction-chip").forEach((chip) => {
            const emoji = chip.dataset.reactionEmoji;
            const count = counts[emoji] || 0;
            chip.querySelector(".reaction-count").textContent = count;
            chip.hidden = count === 0 && !mine.has(emoji);
            chip.classList.toggle("reacted", mine.has(emoji));
        });
    }
}
