// World map (BlueMap) controls.
//
// Render runs out-of-process via BlueMap CLI. Status polled every 3 s while
// the modal is open OR while a render is in progress. The "Open map" button
// only opens the new tab if there's actually rendered output -- otherwise we
// pop a friendly message saying "render first".
"use strict";

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

const els = {};
let pollTimer = null;
let modalOpen = false;
let lastHasOutput = false;

function setPolling(intervalMs) {
    if (pollTimer) clearInterval(pollTimer);
    pollTimer = setInterval(tick, intervalMs);
}

async function tick() {
    let s;
    try { s = await api("/api/map/status"); }
    catch { return; }

    lastHasOutput = !!s.hasOutput;
    document.getElementById("mapBadge").hidden = !s.inProgress;
    if (s.inProgress) document.getElementById("mapBadge").textContent = "rendering";

    if (!modalOpen) return; // don't bother updating modal DOM if hidden

    els.phase.textContent   = phaseLabel(s.phase);
    els.lastLog.textContent = s.lastLogLine ?? "--";
    els.render.disabled = s.inProgress;
    els.render.textContent = s.inProgress ? "Rendering…" : "Render now";
    els.cancel.hidden = !s.inProgress;

    if (s.phase === "complete" || s.phase === "failed" || s.phase === "cancelled") {
        if (s.phase === "failed" && s.error)        showMsg("Failed: " + s.error);
        else if (s.phase === "cancelled")           showMsg("Cancelled. Next render resumes from this point.");
        else if (s.phase === "complete")            showMsg("Render complete.", true);
    }
}

function phaseLabel(phase) {
    switch (phase) {
        case "downloading": return "Downloading CLI";
        case "extracting":  return "Extracting CLI";
        case "configuring": return "Configuring";
        case "rendering":   return "Rendering";
        case "complete":    return "Complete";
        case "failed":      return "Failed";
        case "cancelled":   return "Cancelled";
        default:            return "Idle";
    }
}

function showMsg(text, ok = false) {
    els.msg.className = ok ? "acct-msg ok" : "acct-msg";
    els.msg.textContent = text;
}

export function setupMap() {
    els.phase   = document.getElementById("mapPhase");
    els.lastLog = document.getElementById("mapLastLog");
    els.render  = document.getElementById("mapRender");
    els.cancel  = document.getElementById("mapCancel");
    els.open    = document.getElementById("mapOpen");
    els.msg     = document.getElementById("mapMsg");
    if (!els.render) return;

    els.cancel.addEventListener("click", async () => {
        if (!confirm("Cancel the render? It's resumable -- next time you click Render, BlueMap continues from where it stopped.")) return;
        try {
            const res = await fetch("/api/map/cancel", { method: "POST" });
            const body = await res.json().catch(() => ({}));
            if (!res.ok || body.ok === false) showMsg(body.error || `Error ${res.status}`);
            else { showMsg("Cancelling…"); tick(); }
        } catch (e) { showMsg(e.message); }
    });

    // Track modal open/close so we can poll faster when the user is watching.
    const modal = document.getElementById("modalMap");
    new MutationObserver(() => {
        modalOpen = !modal.hidden;
        if (modalOpen) tick();
    }).observe(modal, { attributes: true, attributeFilter: ["hidden"] });

    els.render.addEventListener("click", async () => {
        showMsg("Starting render…");
        els.render.disabled = true;
        try {
            const res = await fetch("/api/map/render", { method: "POST" });
            const body = await res.json().catch(() => ({}));
            if (!res.ok || body.ok === false) {
                showMsg(body.error || `Error ${res.status}`);
                els.render.disabled = false;
                return;
            }
            tick();
        } catch (e) { showMsg(e.message); els.render.disabled = false; }
    });

    els.open.addEventListener("click", () => {
        if (!lastHasOutput) {
            showMsg("No map output yet -- click Render now first.");
            return;
        }
        window.open("/map/", "_blank", "noopener");
    });

    tick();
    setPolling(3000); // light poll keeps the badge fresh + catches background renders
}
