/*
 * SPDX-License-Identifier: GPL-3.0
 * Aerocord, a vesktop fork for older microsoft NT releases such as NT 6.0, 6.1, 6.2 and 6.3. 
 * Credits to vendicated and the rest of the vesktop contribuitors for making Vesktop!
 */

import { BrowserWindow, dialog } from "electron";
import { writeFile } from "fs/promises";
import { join } from "path";

import { MessageBoxChoice } from "../constants";
import { State } from "../settings";

// Bump this to re-show the prompt
const layoutVersion = 2;
// Get this from "show details" on the profile after exporting as a shared personal layout or using share with community
const layoutId = "3080264545"; // Vesktop Layout v2
const numberRegex = /^[0-9]*$/;

let steamPipeQueue = Promise.resolve();

export const isDeckGameMode = process.env.SteamOS === "1" && process.env.SteamGamepadUI === "1";

export function applyDeckKeyboardFix() {
    if (!isDeckGameMode) return;
    // Prevent constant virtual keyboard spam that eventually crashes Steam.
    process.env.GTK_IM_MODULE = "None";
}

// For some reason SteamAppId is always 0 for non-steam apps so we do this insanity instead.
function getAppId(): string | null {
    // /home/deck/.local/share/Steam/steamapps/shadercache/APPID/fozmediav1
    const path = process.env.STEAM_COMPAT_MEDIA_PATH;
    if (!path) return null;
    const pathElems = path?.split("/");
    const appId = pathElems[pathElems.length - 2];
    if (appId.match(numberRegex)) {
        console.log(`Got Steam App ID ${appId}`);
        return appId;
    }
    return null;
}

export function execSteamURL(url: string) {
    // This doesn't allow arbitrary execution despite the weird syntax.
    steamPipeQueue = steamPipeQueue.then(() =>
        writeFile(
            join(process.env.HOME || "/home/deck", ".steam", "steam.pipe"),
            // replace ' to prevent argument injection
            `'${process.env.HOME}/.local/share/Steam/ubuntu12_32/steam' '-ifrunning' '${url.replaceAll("'", "%27")}'\n`,
            "utf-8"
        )
    );
}

export function steamOpenURL(url: string) {
    execSteamURL(`steam://openurl/${url}`);
}

export async function showGamePage() {
    const appId = getAppId();
    if (!appId) return;
    await execSteamURL(`steam://nav/games/details/${appId}`);
}

async function showLayout(appId: string) {
    execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
}

export async function askToApplySteamLayout(win: BrowserWindow) {
    const appId = getAppId();
    if (!appId) return;
    if (State.store.steamOSLayoutVersion === layoutVersion) return;
    const update = Boolean(State.store.steamOSLayoutVersion);

    // Touch screen breaks in some menus when native touch mode is enabled on latest SteamOS beta, remove most of the update specific text once that's fixed.
    const { response } = await dialog.showMessageBox(win, {
        message: `${update ? "Update" : "Apply"} Vesktop Steam Input Layout?`,
        detail: `Would you like to ${update ? "Update" : "Apply"} Vesktop's recommended Steam Deck controller settings?
${update ? "Click yes using the touchpad" : "Tap yes"}, then press the X button or tap Apply Layout to confirm.${
            update ? " Doing so will undo any customizations you have made." : ""
        }
${update ? "Click" : "Tap"} no to keep your current layout.`,
        buttons: ["Yes", "No"],
        cancelId: MessageBoxChoice.Cancel,
        defaultId: MessageBoxChoice.Default,
        type: "question"
    });

    if (State.store.steamOSLayoutVersion !== layoutVersion) {
        State.store.steamOSLayoutVersion = layoutVersion;
    }

    if (response === MessageBoxChoice.Cancel) return;

    await showLayout(appId);
}
