"""Basic external Javascript lib wrappers"""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/03_js.ipynb.

# %% auto 0
__all__ = ['marked_imp', 'npmcdn', 'light_media', 'dark_media', 'MarkdownJS', 'KatexMarkdownJS', 'HighlightJS', 'SortableJS',
           'MermaidJS']

# %% ../nbs/api/03_js.ipynb
import re
from fastcore.utils import *
from fasthtml.components import *
from fasthtml.xtend import *

# %% ../nbs/api/03_js.ipynb
def light_media(
        css: str # CSS to be included in the light media query
    ):
    "Render light media for day mode views"
    return Style('@media (prefers-color-scheme: light) {%s}' %css)

# %% ../nbs/api/03_js.ipynb
def dark_media(
        css: str # CSS to be included in the dark media query
    ):
    "Render dark media for night mode views"
    return Style('@media (prefers-color-scheme:  dark) {%s}' %css)

# %% ../nbs/api/03_js.ipynb
marked_imp = """import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
"""
npmcdn = 'https://cdn.jsdelivr.net/npm/'

# %% ../nbs/api/03_js.ipynb
def MarkdownJS(
        sel='.marked' # CSS selector for markdown elements
    ):
    "Implements browser-based markdown rendering."
    src = "proc_htmx('%s', e => e.innerHTML = marked.parse(e.textContent));" % sel
    return Script(marked_imp+src, type='module')

# %% ../nbs/api/03_js.ipynb
def KatexMarkdownJS(
        sel='.marked',  # CSS selector for markdown elements
        inline_delim='$',  # Delimiter for inline math
        display_delim='$$',  # Delimiter for long math
        math_envs=None  # List of environments to render as display math
    ):
    math_envs = math_envs or ['equation', 'align', 'gather', 'multline']
    env_list = '[' + ','.join(f"'{env}'" for env in math_envs) + ']'
    fn = Path(__file__).parent/'katex.js'
    scr = ScriptX(fn, display_delim=re.escape(display_delim), inline_delim=re.escape(inline_delim),
                  sel=sel, env_list=env_list, type='module')
    css = Link(rel="stylesheet", href=npmcdn+"katex@0.16.11/dist/katex.min.css")
    return scr,css

# %% ../nbs/api/03_js.ipynb
def HighlightJS(
        sel='pre code:not([data-highlighted="yes"])', # CSS selector for code elements. Default is industry standard, be careful before adjusting it
        langs:str|list|tuple='python',  # Language(s) to highlight
        light='atom-one-light',  # Light theme
        dark='atom-one-dark'  # Dark theme
    ):
    "Implements browser-based syntax highlighting. Usage example [here](/tutorials/quickstart_for_web_devs.html#code-highlighting)."
    src = """
hljs.addPlugin(new CopyButtonPlugin());
hljs.configure({'cssSelector': '%s'});
htmx.onLoad(hljs.highlightAll);""" % sel
    hjs = 'highlightjs','cdn-release', 'build'
    hjc = 'arronhunt'  ,'highlightjs-copy', 'dist'
    if isinstance(langs, str): langs = [langs]
    langjs = [jsd(*hjs, f'languages/{lang}.min.js') for lang in langs]
    return [jsd(*hjs, f'styles/{dark}.css', typ='css', media="(prefers-color-scheme: dark)"),
            jsd(*hjs, f'styles/{light}.css', typ='css', media="(prefers-color-scheme: light)"),
            jsd(*hjs, f'highlight.min.js'),
            jsd(*hjc, 'highlightjs-copy.min.js'),
            jsd(*hjc, 'highlightjs-copy.min.css', typ='css'),
            *langjs, Script(src, type='module')]

# %% ../nbs/api/03_js.ipynb
def SortableJS(
        sel='.sortable',  # CSS selector for sortable elements
        ghost_class='blue-background-class'  # When an element is being dragged, this is the class used to distinguish it from the rest
    ):
    src = """
import {Sortable} from 'https://cdn.jsdelivr.net/npm/sortablejs/+esm';
proc_htmx('%s', Sortable.create);
""" % sel
    return Script(src, type='module')

# %% ../nbs/api/03_js.ipynb
def MermaidJS(
        sel='.language-mermaid',  # CSS selector for mermaid elements
        theme='base',  # Mermaid theme to use
    ):
    "Implements browser-based Mermaid diagram rendering."
    src = """
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';

mermaid.initialize({
    startOnLoad: false,
    theme: '%s',
    securityLevel: 'loose',
    flowchart: { useMaxWidth: false, useMaxHeight: false }
});

function renderMermaidDiagrams(element, index) {
    try {
        const graphDefinition = element.textContent;
        const graphId = `mermaid-diagram-${index}`;
        mermaid.render(graphId, graphDefinition)
            .then(({svg, bindFunctions}) => {
                element.innerHTML = svg;
                bindFunctions?.(element);
            })
            .catch(error => {
                console.error(`Error rendering Mermaid diagram ${index}:`, error);
                element.innerHTML = `<p>Error rendering diagram: ${error.message}</p>`;
            });
    } catch (error) {
        console.error(`Error processing Mermaid diagram ${index}:`, error);
    }
}

// Assuming proc_htmx is a function that triggers rendering
proc_htmx('%s', renderMermaidDiagrams);
""" % (theme, sel)
    return Script(src, type='module')

