import { Plugin, PluginKey } from "../../../../../pm/state.js";
import { capitalize } from "../../../../../lodash.js";
import { globalLogger } from "../../../../../logger.js";
import { PlainTextLang } from "../const.js";
export const codeBlockLangsPluginKey = new PluginKey('code_block_langs');
const defaultState = {
    langItems: [],
    aliasMapping: {},
    lowlight: null,
    loaded: false,
};
export function getCodeBlockLangsState(state) {
    return codeBlockLangsPluginKey.getState(state) ?? defaultState;
}
export function codeBlockLangsPlugin(langsConfig, logger) {
    return new Plugin({
        key: codeBlockLangsPluginKey,
        state: {
            init: (_config, _state) => {
                return defaultState;
            },
            apply: (tr, state) => {
                const meta = tr.getMeta(codeBlockLangsPluginKey);
                if (meta)
                    return meta;
                return state;
            },
        },
        view: (view) => {
            loadAndInit(view, langsConfig, logger);
            return {};
        },
    });
}
async function loadAndInit(view, langsConfig, logger) {
    try {
        const [{ default: hljs }, low] = await Promise.all([
            import('highlight.js/lib/core'),
            import('lowlight'),
        ]);
        const all = low.all;
        const create = low.createLowlight;
        const langs = { ...all, ...langsConfig };
        const lowlight = create(langs);
        const langItems = [];
        const aliasMapping = {};
        for (const lang of Object.keys(langs)) {
            const defs = langs[lang](hljs);
            langItems.push({
                value: lang,
                content: defs.name || capitalize(lang),
            });
            if (defs.aliases) {
                for (const alias of defs.aliases) {
                    aliasMapping[alias] = lang;
                }
            }
        }
        langItems.sort(sortLangs);
        if (!view.isDestroyed) {
            const newState = {
                langItems,
                aliasMapping,
                lowlight,
                loaded: true,
            };
            view.dispatch(view.state.tr.setMeta(codeBlockLangsPluginKey, newState));
        }
    }
    catch (e) {
        globalLogger.info('Skip code_block highlighting');
        logger.log('Skip code_block highlighting');
    }
}
function sortLangs(a, b) {
    // plaintext always goes first
    if (a.value === PlainTextLang)
        return -1;
    if (b.value === PlainTextLang)
        return 1;
    return 0;
}
//# sourceMappingURL=codeBlockLangsPlugin.js.map
