class MicronParser {

    /**
     * Set a custom scheme for urls set on html links.
     * This just makes the browser show a pretty url when hovering links, but in the future, I may implement url
     * interception, rather than using an onclick script on the link element itself.
     */
    static formatNomadnetworkUrl(url) {
        return `nomadnetwork://${url}`;
    }

    /**
     * Converts micron markup to html.
     * FIXME: make sure you can't inject javascript into Reticulum MeshChat browser from micron page content!
     *
     * Known URL Examples:
     * - :
     * - :/page/index.mu
     * - :/page/somefolder/somefile.mu
     * - :/file/somefile.ext
     * - 00000000000000000000000000000000
     * - 00000000000000000000000000000000:/page/index.mu
     * - 00000000000000000000000000000000:/page/somefolder/somefile.mu
     * - 00000000000000000000000000000000:/file/somefile.ext
     * - lxmf@00000000000000000000000000000000
     *
     * References:
     * - https://github.com/markqvist/NomadNet/blob/6a4f2026249b22a00f6ff98c12d06fd5b160a90d/nomadnet/ui/textui/MicronParser.py
     */
    static convertMicronToHtml(markup) {

        console.log(markup);

        // split by line
        var lines = markup.split("\n");

        // parse each line
        lines = lines.map((line) => {

            // skip comments
            if(line.startsWith("#")){
                return null;
            }

            // skip section heading reset
            // FIXME: implement
            if(line === "<"){
                return null;
            }

            // skip background colours
            // FIXME: implement
            line = line.replaceAll(/`B([0-9A-Fa-f]+)/g, function(match, colourCode) {
                return "";
            });

            // skip default background colour
            // FIXME: implement
            line = line.replaceAll(/`b/g, function(match) {
                return "";
            });

            // skip literal
            // FIXME: implement
            line = line.replaceAll(/`=/g, function(match) {
                return "";
            });

            // skip reset formatting
            // FIXME: implement
            if(line.startsWith("``")){
                line = line.replace("``", "");
            }

            // parse micron links
            // `[ ◈  The Future of RNode: A New Model`:/page/posts/2022_06_27.mu]
            line = line.replaceAll(/`\[(.*?)`(.*?)\]/g, function(match, linkText, linkUrl) {
                const url = MicronParser.formatNomadnetworkUrl(linkUrl);
                return `<a href="${url}" onclick="event.preventDefault(); onNodePageUrlClick('${linkUrl}')">${linkText}</a>`
            });

            // parse markdown links
            // [Reticulum](https://github.com/markqvist/Reticulum)
            line = line.replaceAll(/\[(.*?)\]\((.*?)\)/g, function(match, linkText, linkUrl) {
                const url = MicronParser.formatNomadnetworkUrl(linkUrl);
                return `<a href="${url}" onclick="event.preventDefault(); onNodePageUrlClick('${linkUrl}')" style="text-decoration:underline;">${linkText}</a>`
            });

            // parse bold
            // `!Bold Text`!
            line = line.replaceAll(/`!(.*?)`!/g, function(match, text) {
                return `<span style="font-weight:bold;">${text}</span>`
            });

            // parse italics
            // `*Italic Text`*
            line = line.replaceAll(/`\*(.*?)`\*/g, function(match, text) {
                return `<span style="font-style:italic;">${text}</span>`
            });

            // parse underline
            // `_Underlined Text`_
            line = line.replaceAll(/`_(.*?)`_/g, function(match, text) {
                return `<span style="text-decoration:underline;">${text}</span>`
            });

            // parse divider
            // FIXME: use raw css, not tailwind classes for styling
            if(line.trim() === "-"){
                line = "<hr class='border-gray-500'/>"
            }

            // parse divider (custom character)
            // FIXME: use raw css, not tailwind classes for styling
            // FIXME: use custom divider character
            if(line.startsWith("-") && line.length === 2){
                line = "<hr class='border-gray-500'/>"
            }

            // parse depth (should be full width)
            // FIXME: use raw css, not tailwind classes for styling
            if(line.startsWith(">>>")){
                line = line.replace(">>>", "");
                line = `<span class='inline-block w-full bg-gray-100 text-black pl-3'>${line}</span>`
            } else if(line.startsWith(">>")){
                line = line.replace(">>", "");
                line = `<span class='inline-block w-full bg-gray-100 text-black pl-2'>${line}</span>`
            } else if(line.startsWith(">")){
                line = line.replace(">", "");
                line = `<span class='inline-block w-full bg-gray-100 text-black pl-1'>${line}</span>`
            }

            // align (default: using left)
            if(line.startsWith("`a")){
                line = line.replace("`a", "");
                line = `<span style="text-align:left;">${line}</span>`;
            }

            // align center
            if(line.startsWith("`c")){
                line = line.replace("`c", "");
                line = `<span style="text-align:center;">${line}</span>`;
            }

            // align left
            if(line.startsWith("`l")){
                line = line.replace("`l", "");
                line = `<span style="text-align:left;">${line}</span>`;
            }

            // align right
            if(line.startsWith("`r")){
                line = line.replace("`l", "");
                line = `<span style="text-align:right;">${line}</span>`;
            }

            // formatted content
            // `Ff00 red content `f
            line = line.replaceAll(/`F([0-9A-Fa-f]+)(.*?)`f/g, function(match, colourCode, content) {
                return `<span style="color:#${colourCode}">${content}</span>`
            });

            return line;

        });

        // filter out null items, and join with line break
        return lines.filter((line) => {
            return line != null;
        }).join("<br/>");

    }

}