// retoor <retoor@molodetz.nl>

import { Http } from "./Http.js";
import { Poller } from "./Poller.js";

const IDLE_INTERVAL_MS = 20000;
const TRANSITION_INTERVAL_MS = 2000;
const TRANSITIONAL_PHASES = ["starting", "stopping"];

export class WorkspaceManager {
    constructor(root) {
        this.root = root;
        this.slug = root.dataset.slug;
        this.uid = root.dataset.workspaceUid || "";
        this.ownerUid = root.dataset.ownerUid || "";
        this.phase = root.dataset.phase || "";
        this.poller = null;
        this.interval = 0;
        this.bind();
        this.subscribe();
        this.poll(this.isTransitional(this.phase));
    }

    static mount() {
        const root = document.querySelector("[data-workspace-root]");
        return root ? new WorkspaceManager(root) : null;
    }

    bind() {
        this.root.addEventListener("submit", (event) => {
            const form = event.target.closest("form[data-workspace-action]");
            if (!form) return;
            event.preventDefault();
            this.send(form);
        });
    }

    async send(form) {
        const button = form.querySelector("button[type='submit']");
        this.setBusy(button, true);
        try {
            await Http.sendForm(form.action, this.params(form), { silent: true });
            await this.refresh();
        } catch (error) {
            this.toast(error.message || "Action failed", "error");
        } finally {
            this.setBusy(button, false);
        }
    }

    setBusy(button, busy) {
        if (!button) return;
        button.disabled = busy;
        button.classList.toggle("is-loading", busy);
    }

    params(form) {
        const params = [];
        new FormData(form).forEach((value, key) => params.push([key, value]));
        return params;
    }

    toast(message, type) {
        if (window.app && window.app.toast) window.app.toast.show(message, { type: type });
    }

    subscribe() {
        const pubsub = window.app && window.app.pubsub;
        if (!pubsub || !this.uid || !this.ownerUid) return;
        pubsub.subscribe(`user.${this.ownerUid}.workspace.${this.uid}`, (data) => this.render(data));
    }

    isTransitional(phase) {
        return TRANSITIONAL_PHASES.includes(phase);
    }

    poll(fast) {
        const interval = fast ? TRANSITION_INTERVAL_MS : IDLE_INTERVAL_MS;
        if (this.poller && this.interval === interval) return;
        if (this.poller) this.poller.stop();
        this.interval = interval;
        this.poller = new Poller(() => this.refresh(), interval, {
            immediate: false,
            pauseHidden: true,
        });
    }

    async refresh() {
        const data = await Http.getJson(`/projects/${this.slug}/workspace`);
        this.render(data);
    }

    render(data) {
        if (!data || !data.workspace) return;
        const workspace = data.workspace;
        const badge = this.root.querySelector("[data-workspace-phase]");
        if (badge) {
            badge.textContent = workspace.phase_label || workspace.phase || "";
            badge.className = `workspace-badge workspace-badge-${workspace.phase}`;
        }
        const status = this.root.querySelector("[data-workspace-status]");
        if (status) status.textContent = workspace.status || "";
        const launch = this.root.querySelector("[data-editor-open]");
        if (launch && data.editor_url) launch.href = data.editor_url;
        this.applyPhase(workspace.phase);
        if (workspace.phase === "ready" && this.phase === "starting") {
            this.toast("Your workspace is ready", "success");
        }
        this.phase = workspace.phase;
        this.root.dataset.phase = workspace.phase;
        this.poll(this.isTransitional(workspace.phase));
    }

    applyPhase(phase) {
        for (const view of this.root.querySelectorAll("[data-phase-view]")) {
            const phases = view.dataset.phaseView.split(/\s+/);
            view.hidden = !phases.includes(phase);
        }
    }
}

export default WorkspaceManager;
