import * as fs from "node:fs";
import * as path from "node:path";
import { getCustomThemesDir, getThemesDir } from "../../../config.js";
import { detectColorMode, resolveThemeColors } from "./color-utils.js";
import { assertThemeNameIsValid, parseThemeJsonContent } from "./theme-parse.js";
import { Theme } from "./theme-class.js";
let BUILTIN_THEMES;
const registeredThemes = new Map();
export function getBuiltinThemes() {
    if (!BUILTIN_THEMES) {
        const themesDir = getThemesDir();
        const themes = {};
        for (const file of fs.readdirSync(themesDir).sort()) {
            if (!file.endsWith(".json") || file === "theme-schema.json") {
                continue;
            }
            const themePath = path.join(themesDir, file);
            const themeJson = parseThemeJsonContent(themePath, fs.readFileSync(themePath, "utf-8"));
            themes[themeJson.name] = themeJson;
        }
        BUILTIN_THEMES = themes;
    }
    return BUILTIN_THEMES;
}
export function getAvailableThemes() {
    return getAvailableThemesWithPaths().map(({ name }) => name);
}
export function getAvailableThemesWithPaths() {
    const themesDir = getThemesDir();
    const result = [];
    const seen = new Set();
    const addTheme = (info) => {
        if (seen.has(info.name))
            return;
        seen.add(info.name);
        result.push(info);
    };
    // Built-in themes
    for (const name of Object.keys(getBuiltinThemes())) {
        addTheme({ name, path: path.join(themesDir, `${name}.json`) });
    }
    // Custom themes
    for (const info of getCustomThemeInfos()) {
        addTheme(info);
    }
    for (const [name, theme] of registeredThemes.entries()) {
        addTheme({ name, path: theme.sourcePath });
    }
    return result.sort((a, b) => a.name.localeCompare(b.name));
}
function getCustomThemeInfos() {
    const customThemesDir = getCustomThemesDir();
    const result = [];
    if (!fs.existsSync(customThemesDir)) {
        return result;
    }
    for (const file of fs.readdirSync(customThemesDir)) {
        if (!file.endsWith(".json")) {
            continue;
        }
        const themePath = path.join(customThemesDir, file);
        try {
            const customTheme = loadThemeFromPath(themePath);
            if (customTheme.name) {
                result.push({ name: customTheme.name, path: themePath });
            }
        }
        catch {
            // Invalid themes are ignored here; the resource loader reports them
            // during normal startup/reload.
        }
    }
    return result;
}
export function loadThemeJson(name) {
    const builtinThemes = getBuiltinThemes();
    if (name in builtinThemes) {
        return builtinThemes[name];
    }
    const registeredTheme = registeredThemes.get(name);
    if (registeredTheme?.sourcePath) {
        const content = fs.readFileSync(registeredTheme.sourcePath, "utf-8");
        return parseThemeJsonContent(registeredTheme.sourcePath, content);
    }
    if (registeredTheme) {
        throw new Error(`Theme "${name}" does not have a source path for export`);
    }
    const customThemesDir = getCustomThemesDir();
    const themePath = path.join(customThemesDir, `${name}.json`);
    if (!fs.existsSync(themePath)) {
        throw new Error(`Theme not found: ${name}`);
    }
    const content = fs.readFileSync(themePath, "utf-8");
    return parseThemeJsonContent(name, content);
}
function createTheme(themeJson, mode, sourcePath) {
    const colorMode = mode ?? detectColorMode();
    const resolvedColors = resolveThemeColors(themeJson.colors, themeJson.vars);
    const fgColors = {};
    const bgColors = {};
    const bgColorKeys = new Set([
        "selectedBg",
        "userMessageBg",
        "customMessageBg",
        "toolPendingBg",
        "toolSuccessBg",
        "toolErrorBg",
    ]);
    for (const [key, value] of Object.entries(resolvedColors)) {
        if (bgColorKeys.has(key)) {
            bgColors[key] = value;
        }
        else {
            fgColors[key] = value;
        }
    }
    return new Theme(fgColors, bgColors, colorMode, {
        name: themeJson.name,
        sourcePath,
    });
}
export function loadThemeFromPath(themePath, mode) {
    const content = fs.readFileSync(themePath, "utf-8");
    return loadThemeFromContent(themePath, content, mode);
}
export function loadThemeFromContent(themePath, content, mode) {
    const themeJson = parseThemeJsonContent(themePath, content);
    return createTheme(themeJson, mode, themePath);
}
export function loadTheme(name, mode) {
    const registeredTheme = registeredThemes.get(name);
    if (registeredTheme) {
        return registeredTheme;
    }
    const themeJson = loadThemeJson(name);
    return createTheme(themeJson, mode);
}
export function getThemeByName(name) {
    try {
        return loadTheme(name);
    }
    catch {
        return undefined;
    }
}
export function setRegisteredThemes(themes) {
    registeredThemes.clear();
    for (const theme of themes) {
        if (theme.name) {
            assertThemeNameIsValid(theme.name);
            registeredThemes.set(theme.name, theme);
        }
    }
}
export function setRegisteredTheme(name, theme) {
    registeredThemes.set(name, theme);
}
//# sourceMappingURL=theme-loading.js.map