#!/bin/bash

set -e

BASE="js/spa"
MAIN="js/app.js"

echo "Installing SPA module structure..."

# Create directories
mkdir -p "$BASE"

# Write core.js
cat > "$BASE/core.js" << 'EOF'
export const state = {
    main: null,
    spinner: null,
    errorPanel: null,
    debugPanel: null
};

export function initState() {
    state.main = document.querySelector(".app-main");
    state.spinner = document.querySelector(".app-spinner");
    state.errorPanel = document.querySelector(".app-error");
    state.debugPanel = document.querySelector(".app-debug");
}
EOF

# Write debug.js
cat > "$BASE/debug.js" << 'EOF'
import { state } from "./core.js";

export function debug(msg) {
    console.log("[SPA DEBUG]", msg);
    if (!state.debugPanel) return;
    state.debugPanel.style.display = "block";
    state.debugPanel.innerHTML += `<div>${msg}</div>`;
}

export function error(msg) {
    console.error("[SPA ERROR]", msg);
    if (!state.debugPanel) return;
    state.debugPanel.innerHTML += `<div style='color:red'>${msg}</div>`;
}
EOF

# Write spinner.js
cat > "$BASE/spinner.js" << 'EOF'
import { state } from "./core.js";

export function showSpinner() {
    if (state.spinner) state.spinner.style.display = "block";
}

export function hideSpinner() {
    if (state.spinner) state.spinner.style.display = "none";
}
EOF

# Write errors.js
cat > "$BASE/errors.js" << 'EOF'
import { state } from "./core.js";

export function showError(msg) {
    if (!state.errorPanel) return;

    state.errorPanel.innerHTML = `
        <div class="alert alert-danger">
            <strong>Error:</strong> ${msg}
        </div>
    `;

    state.errorPanel.style.display = "block";

    setTimeout(() => {
        state.errorPanel.style.display = "none";
    }, 5000);
}
EOF

# Write router.js
cat > "$BASE/router.js" << 'EOF'
import { loadPage } from "./loader.js";

export function initRouter() {
    window.addEventListener("popstate", (event) => {
        if (event.state?.url) {
            loadPage(event.state.url, false);
        }
    });
}
EOF

# Write loader.js
cat > "$BASE/loader.js" << 'EOF'
import { state } from "./core.js";
import { showSpinner, hideSpinner } from "./spinner.js";
import { showError } from "./errors.js";
import { debug } from "./debug.js";

export function loadPage(url, pushHistory = true) {
    if (!state.main) return;

    showSpinner();
    debug("Loading: " + url);

    fetch(url)
        .then(res => {
            if (!res.ok) throw new Error("HTTP " + res.status);
            return res.text();
        })
        .then(html => {
            state.main.innerHTML = html;
            hideSpinner();
            window.scrollTo({ top: 0, behavior: "smooth" });

            if (pushHistory) {
                history.pushState({ url }, "", `#${url}`);
            }
        })
        .catch(err => {
            hideSpinner();
            showError(`Failed to load ${url}: ${err.message}`);
            debug("ERROR: " + err.message);
        });
}
EOF

# Write app.js
mkdir -p "$(dirname "$MAIN")"
cat > "$MAIN" << 'EOF'
import { initState } from "./spa/core.js";
import { initRouter } from "./spa/router.js";
import { loadPage } from "./spa/loader.js";
import { debug } from "./spa/debug.js";

document.addEventListener("DOMContentLoaded", () => {
    initState();
    initRouter();

    debug("SPA initialized");

    const hash = location.hash.replace("#", "");
    if (hash) {
        loadPage(hash, false);
    }
});
EOF

echo "SPA installation complete."
echo "Add this to your HTML:"
echo "<script type=\"module\" src=\"/assets/js/app.js\"></script>"

