const { parse_arg, getWindowControlLayout, getTitleFont, pangoToCss } = require("../utils/swai_utils.js");
const { unquoteGsettingsString } = require("../utils/GsettingsMonitor.js");
const {ipcRenderer} = require('electron');

document.querySelector(".window-title").textContent = parse_arg("--webappName") ?? "SWAI Web App";
ipcRenderer.on("app-name-changed", (_event, appName) => {
    document.querySelector(".window-title").textContent = appName;
});
console.log(parse_arg("--windowId"))
let windowId = parseInt(parse_arg("--windowId")) ?? 0;

const leftContainer = document.querySelector(".window-controls.left");
const rightContainer = document.querySelector(".window-controls.right");
const titlebar = document.querySelector("#titlebar");

// Keep the title centered against the full window, not merely centered in the
// unequal space between the navigation buttons and window controls. Reserve an
// equal inset on both sides based on whichever control group is wider so long
// titles still ellipsize before reaching a button.
function updateTitleControlInset() {
    const leftWidth = leftContainer.getBoundingClientRect().width;
    const rightWidth = rightContainer.getBoundingClientRect().width;
    const safeInset = Math.ceil(Math.max(leftWidth, rightWidth) + 24);
    titlebar.style.setProperty("--titlebar-control-inset", `${safeInset}px`);
}

const controlResizeObserver = new ResizeObserver(updateTitleControlInset);
controlResizeObserver.observe(leftContainer);
controlResizeObserver.observe(rightContainer);

// Cache the latest back/forward enabled state so we can re-apply it whenever
// the button row is re-rendered (e.g. after a gsettings button-layout change).
let lastNavState = { canBack: false, canForward: false };

function createButton(type, iconPath) {
    const button = document.createElement("button");
    button.className = `window-button ${type} no-drag`;

    const img = document.createElement("img");
    img.src = iconPath;
    img.draggable = false;
    img.style.width = "16px";
    img.style.height = "16px";
    img.style.color = "#ffffff";

    button.appendChild(img);
    button.onclick = () => {
        ipcRenderer.send(`${type}-${windowId}`);
    };
    return button;
}

function addControl(control, container) {
    switch (control) {
        case "minimize":
            container.appendChild(createButton(
                "minimize",
                "../../icons/window-minimize-symbolic.svg"
            ));
            break;
        case "maximize":
            container.appendChild(createButton(
                "maximize",
                "../../icons/window-maximize-symbolic.svg"
            ));
            break;
        case "close":
            container.appendChild(createButton(
                "close",
                "../../icons/window-close-symbolic.svg"
            ));
            break;
    }
}

function parseButtonLayout(layoutString) {
    const fallback = { left: [], right: ["minimize", "maximize", "close"] };
    if (!layoutString || typeof layoutString !== "string") return fallback;

    try {
        const split = layoutString.split(":");
        if (split.length === 2) {
            return {
                left: split[0] ? split[0].split(",").filter(Boolean) : [],
                right: split[1] ? split[1].split(",").filter(Boolean) : [],
            };
        }
    } catch (_) {
        // fall through
    }
    return fallback;
}

/**
 * Rebuild the left/right window-control containers from a layout string
 * like "appmenu:minimize,maximize,close". Safe to call repeatedly.
 */
function applyButtonLayout(layoutString) {
    leftContainer.replaceChildren();
    rightContainer.replaceChildren();

    const { left, right } = parseButtonLayout(layoutString);
    left.forEach(c => addControl(c, leftContainer));
    right.forEach(c => addControl(c, rightContainer));

    const back_button = createButton("back", "../../icons/go-previous-symbolic.svg");
    back_button.classList.add("flat");
    back_button.disabled = !lastNavState.canBack;

    const forward_button = createButton("forward", "../../icons/go-next-symbolic.svg");
    forward_button.classList.add("flat");
    forward_button.disabled = !lastNavState.canForward;

    if (leftContainer.children.length <= rightContainer.children.length) {
        leftContainer.append(back_button);
        leftContainer.append(forward_button);
    } else {
        // Prepend in reverse so the final order is [back, forward, ...controls]
        // (each prepend pushes the new node to position 0).
        rightContainer.prepend(forward_button);
        rightContainer.prepend(back_button);
    }

    updateTitleControlInset();
}

/**
 * Apply a Pango-style font string (as returned by gsettings) to the title.
 */
function applyTitleFont(fontName) {
    if (!fontName) return;
    const { fontStyle, fontSize } = pangoToCss(fontName);
    const title = document.querySelector(".window-title");
    title.style.fontFamily = '"Adwaita Sans", sans-serif';
    title.style.fontWeight = "Bold";
    title.style.fontStyle = fontStyle;
    title.style.fontSize = fontSize;
}

async function setupWindowControls() {
    let windowControls = null;
    let fontName = null;

    try {
        windowControls = await getWindowControlLayout();
    } catch (e) {
        console.warn("Failed to read window control layout from gsettings:", e);
    }
    try {
        fontName = await getTitleFont();
    } catch (e) {
        console.warn("Failed to read title font from gsettings:", e);
    }

    applyButtonLayout(windowControls);
    applyTitleFont(fontName);
}

setupWindowControls().catch(error => {
    console.error("Failed to setup window controls:", error);
    // Last-ditch fallback so the window is still usable.
    applyButtonLayout(null);
});

/**
 * Set the titlebar background color dynamically
 * @param {string|null} color - Hex color string (e.g., "#ffffff") or null for default
 * @param {boolean|null} isLight - Whether the color is light (for text contrast) or null for auto-detect
 */
function set_color_titlebar(color, isLight) {
    const root = document.documentElement;

    if (!color) {
        root.style.removeProperty('--headerbar-bg');
        root.style.removeProperty('--headerbar-fg');
        document.body.classList.remove('custom-theme-color', 'theme-light', 'theme-dark');
        return;
    }

    root.style.setProperty('--headerbar-bg', color);

    const textColor = isLight ? '#000000' : '#ffffff';
    root.style.setProperty('--headerbar-fg', textColor);

    document.body.classList.add('custom-theme-color');
    document.body.classList.remove('theme-light', 'theme-dark');
    document.body.classList.add(isLight ? 'theme-light' : 'theme-dark');
}

ipcRenderer.on(`url-changed-${windowId}`, (event, title, can_back, can_forward) => {
    document.querySelector(".window-title").textContent = title;
    lastNavState = { canBack: !!can_back, canForward: !!can_forward };
    const backBtn = document.querySelector(".window-button.back");
    const forwardBtn = document.querySelector(".window-button.forward");
    if (backBtn) backBtn.disabled = !can_back;
    if (forwardBtn) forwardBtn.disabled = !can_forward;
});

ipcRenderer.on(`window-state-change-${windowId}`, (event, isMaximized) => {
    const maximizeButtons = document.querySelectorAll(".window-button.maximize");
    maximizeButtons.forEach(button => {
        button.innerHTML = isMaximized ? restoreSVG : maximizeSVG;
        button.title = isMaximized ? "Restore" : "Maximize";
    });
});

ipcRenderer.on(`theme-color-changed-${windowId}`, (event, themeData) => {
    if (themeData && themeData.color) {
        set_color_titlebar(themeData.color, themeData.isLight);
    } else {
        set_color_titlebar(null, null);
    }
});

// React to live gsettings changes pushed from the main process.
// Payload shape: { schema, key, value } where `value` is the raw gsettings
// string (still wrapped in single quotes for string-typed keys).
ipcRenderer.on(`gsettings-changed-${windowId}`, (event, payload) => {
    if (!payload || !payload.key) return;
    const value = unquoteGsettingsString(payload.value);

    switch (payload.key) {
        case "button-layout":
            applyButtonLayout(value);
            break;
        case "font-name":
            applyTitleFont(value);
            break;
        default:
            break;
    }
});
