// Modpack update controls.
//
// The card hides itself when there's no update available and reveals when the
// manifest reports a newer pack version. Polls /api/update/status (every 5 s
// when idle, every 1 s when an update is in-flight) to keep state fresh.
"use strict";

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

const els = {};
let pollTimer = null;
let pollInterval = 5000;

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

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

    els.current.textContent   = s.current ?? "--";
    els.available.textContent = s.available ?? "--";

    const card = els.card;
    if (s.needsUpdate || s.inProgress) {
        card.hidden = false;
        card.classList.toggle("has-update", s.needsUpdate && !s.inProgress);
    } else {
        card.hidden = true;
    }

    if (s.inProgress) {
        els.progress.hidden = false;
        els.start.disabled = true;
        els.delay.disabled = true;
        els.phase.textContent = phaseLabel(s.phase);

        const showCancel = s.phase === "countdown";
        els.cancel.hidden = !showCancel;

        if (s.phase === "countdown" && s.countdownTotal > 0) {
            const elapsed = s.countdownTotal - s.countdownRemaining;
            const pct = (elapsed / s.countdownTotal) * 100;
            els.fill.style.width = `${pct}%`;
            els.status.textContent = `Restarting in ${formatSeconds(s.countdownRemaining)}`;
        } else {
            // Indeterminate during sync / loader install / start phases --
            // just show 100% and a phase-specific status string.
            els.fill.style.width = "100%";
            els.status.textContent = phaseStatus(s.phase);
        }
        setPolling(1000);
    } else {
        els.progress.hidden = true;
        els.start.disabled = !s.needsUpdate;
        els.delay.disabled = false;
        if (s.phase === "failed" && s.error) {
            els.progress.hidden = false;
            els.phase.textContent = "FAILED";
            els.status.textContent = s.error;
            els.fill.style.width = "0%";
        }
        setPolling(5000);
    }
}

function phaseLabel(phase) {
    switch (phase) {
        case "countdown":          return "COUNTDOWN";
        case "stopping":           return "STOPPING";
        case "syncing":            return "SYNCING MODS";
        case "installing_loader":  return "INSTALLING LOADER";
        case "starting":           return "STARTING";
        case "complete":           return "COMPLETE";
        case "failed":             return "FAILED";
        case "cancelled":          return "CANCELLED";
        default:                   return "WORKING";
    }
}

function phaseStatus(phase) {
    switch (phase) {
        case "stopping":           return "Stopping Minecraft cleanly...";
        case "syncing":            return "Syncing mods from manifest...";
        case "installing_loader":  return "Re-running NeoForge installer...";
        case "starting":           return "Starting Minecraft...";
        case "complete":           return "Update complete.";
        default:                   return "";
    }
}

function formatSeconds(s) {
    if (s < 60) return `${s}s`;
    const m = Math.floor(s / 60), r = s % 60;
    return `${m}m ${String(r).padStart(2, "0")}s`;
}

export function setupUpdate() {
    els.card      = document.getElementById("updateCard");
    els.current   = document.getElementById("updCurrent");
    els.available = document.getElementById("updAvailable");
    els.delay     = document.getElementById("updDelay");
    els.start     = document.getElementById("updStart");
    els.progress  = document.getElementById("updProgress");
    els.phase     = document.getElementById("updPhaseLabel");
    els.fill      = document.getElementById("updProgressFill");
    els.status    = document.getElementById("updStatusText");
    els.cancel    = document.getElementById("updCancel");

    els.start.addEventListener("click", async () => {
        const delay = parseInt(els.delay.value, 10);
        if (!Number.isFinite(delay) || delay < 0) {
            alert("Enter a non-negative warning duration.");
            return;
        }
        if (!confirm(`Update modpack? Players get a ${delay}s warning, then the server restarts.`)) return;
        try {
            await apiJson("/api/update/start", { delaySeconds: delay });
            await tick();
        } catch (e) { alert(e.message); }
    });

    els.cancel.addEventListener("click", async () => {
        if (!confirm("Cancel the countdown? Update will be aborted; server stays running.")) return;
        try {
            await apiJson("/api/update/cancel", {});
            await tick();
        } catch (e) { alert(e.message); }
    });

    tick();
    setPolling(5000);
}
