// retoor <retoor@molodetz.nl>

const REFRESH_MS = 60000;

export class LocalTime {
    constructor() {
        this.localize(document);
        this.observer = new MutationObserver((mutations) => {
            for (const mutation of mutations) {
                for (const node of mutation.addedNodes) {
                    if (node.nodeType === 1) this.localize(node);
                }
            }
        });
        if (document.body) {
            this.observer.observe(document.body, { childList: true, subtree: true });
        }
        window.setInterval(() => this.refreshRelative(), REFRESH_MS);
    }

    format(iso, mode) {
        const date = new Date(iso);
        if (isNaN(date.getTime())) return null;
        if (mode === "ago") return this.relative(date);
        if (mode === "award") {
            const weekday = date.toLocaleDateString([], { weekday: "long" });
            const day = String(date.getDate()).padStart(2, "0");
            const month = String(date.getMonth() + 1).padStart(2, "0");
            const year = date.getFullYear();
            return `${weekday}, ${day}-${month}-${year}`;
        }
        if (mode === "date") return date.toLocaleDateString();
        if (mode === "time") {
            return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
        }
        return date.toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
    }

    relative(date) {
        const seconds = (Date.now() - date.getTime()) / 1000;
        if (seconds < 0) return "just now";
        if (seconds < 60) return "just now";
        const minutes = Math.floor(seconds / 60);
        if (minutes < 60) return minutes + "m ago";
        const hours = Math.floor(minutes / 60);
        if (hours < 24) return hours + "h ago";
        const days = Math.floor(hours / 24);
        if (days <= 30) return days + "d ago";
        return date.toLocaleDateString();
    }

    apply(el) {
        const iso = el.getAttribute("datetime");
        if (!iso) return;
        const mode = el.dataset.dtMode || "datetime";
        const text = this.format(iso, mode);
        if (text === null) return;
        el.textContent = text;
        const full = new Date(iso);
        if (!isNaN(full.getTime())) {
            el.title = full.toLocaleString([], { dateStyle: "full", timeStyle: "long" });
        }
    }

    localize(root) {
        if (root.matches && root.matches("[data-dt]")) this.apply(root);
        if (!root.querySelectorAll) return;
        root.querySelectorAll("[data-dt]").forEach((el) => this.apply(el));
    }

    refreshRelative() {
        if (document.hidden) return;
        const relative = document.querySelectorAll('[data-dt][data-dt-mode="ago"]');
        if (!relative.length) return;
        relative.forEach((el) => this.apply(el));
    }
}
