{% macro pretty_print_dict(d, indent=0) %}
    {% for key, value in d.items() %}
    {{ '  ' * indent }}<code class="key">{{ key }}</code>:
    {% if value is mapping %}
        {{ pretty_print_dict(value, indent + 1) }}
    {% else %}
        {{ '  ' * (indent + 1) }}<code>{{ value|e }}</code><br>
    {% endif %}
    {% endfor %}
{% endmacro %}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Liara - Resource view</title>
        <style>
            code, pre {
                font-size: 1rem;
            }

            a.expand {
                text-decoration: none;

                &:hover {
                    background-color: #DDD;
                }
            }

            li[aria-expanded="false"] .children {
                display: none;
            }

            .details[aria-expanded="false"] {
                display: none;
            }

            .metadata {

                background-color: #EEE;
            }

            .details {
                border-top: 1px solid #CCC;
                padding: 0.25rem;

                display: grid;
                grid-template-columns: auto 1fr;
                gap: 1px;
                
                > .key {
                    grid-column: 1;
                    background-color: #DDD;
                    padding: 0.25rem;
                }

                > .value {
                    grid-column: 2;
                    padding: 0.25rem;
                    background-color: #FFF;
                }

                .index {
                    overflow-y: scroll;

                    ul {
                        margin: 0;
                        padding: 0;

                        li {
                            font-family: monospace;
                            font-size: 1rem;
                        }
                    }
                }

                .metadata {
                    display: block;
                    padding-left: 1rem;
                }
            }

            code.key {
                font-weight: bold;
            }

            html, body {
                margin: 0;
                height: 100%;
            }

            body {
                display: grid;
                grid-template-columns: 1fr 5px 3fr;
                padding: 0;
            }

            .splitter {
                display: block;
                height: 100%;
                width: 1px;
                border-left: 4px solid rgb(255,255,255);
                background-color: green;

                &:hover, &.hover {
                    border-left: none;
                    width: 5px;
                    cursor: ew-resize;
                }
            }

            iframe {
                border: none;
                width: 100%;
                height: 100%;
                display: block; /* Otherwise, there's some extra whitespace after */
            }

            #navigation {
                display: grid;
                grid-template-rows: 2fr 1fr;
                max-height: 100vh;

                ul {
                    overflow-y: scroll;
                }

                a.highlighted {
                    color: red;
                }

                > .metadata {
                    overflow: scroll;
                }
            }
        </style>
    </head>
    <body>
        <section id="navigation">
        <ul>
        {%- for item in nodes recursive %}
            <li aria-expanded="false">
                {%- if item.children %}<a class="expand" href="#" onclick="toggleTree(event)" title="{{ item.children|length }} children">➕</a>{%- endif -%}
                {% if item.data %}
                <a href="#" onclick="select(event)" data-path="{{ item.data.path }}"><code>{{ item.name }}</code></a>
                
                {% else %}
                <code>{{ item.name }}</code>{% if item.path|string == '/' %} (<a href="#" onclick="preview(event)" data-path="/">preview</a>){% endif %}
                {% endif %}
            {%- if item.children -%}
                <ul class="children">{{ loop(item.children) }}</ul>
            {%- endif %}</li>
        {%- endfor %}
        </ul>
        <div class="metadata">
        {%- for item in nodes recursive %}
            {% if item.data %}
            <div class="details" aria-expanded="false" data-path="{{ item.data.path }}">
                <span class="key">Source file</span>
                <code class="value">{{ item.data.src|default("Generated") }}</code>

                <span class="key">Node kind</span>
                <span class="value">{{ item.data.kind.name }}</span>
                {%- if item.data.metadata -%}
                <span class="key">Metadata</span>
                <div class="value">{{ pretty_print_dict(item.data.metadata) }}</div>
                {%- endif -%}
                {%- if is_index_node(item.data) -%}
                <span class="key">References</span>
                <div class="value">
                    <div class="index">
                        <ul>
                            {% for ref in item.data.references %}
                            <li>{{ ref.path }}</li>
                            {% endfor %}
                        </ul>
                    </div>
                </div>
                {%- endif -%}
            </div>
            {% endif %}
            {%- if item.children -%}
                {{ loop(item.children) }}
            {%- endif %}</li>
        {%- endfor %}
        </div>
        </section>
        <div class="splitter"></div>
        <section>
            <iframe id="preview" src="/">
            </iframe>
        </section>
    </body>
    <script defer>
    function select(event) {
        const path = event.target.closest("a").getAttribute("data-path");
        showDetails(path);
        preview(path);

        event.preventDefault();
    }

    function preview(path) {
        document.getElementById("preview").src = path;
    }

    function showDetails(path) {
        document.querySelectorAll(".details").forEach((e) => e.setAttribute("aria-expanded", "false"));
        const detailsElement = document.querySelector(`.details[data-path="${path}"]`);
        detailsElement.setAttribute("aria-expanded", "true");
    }

    function toggleTree(event) {
        const liElement = event.target.closest("li");
        if (liElement.getAttribute("aria-expanded") == "false") {
            liElement.setAttribute("aria-expanded", "true");
            event.target.innerText = '➖';
        } else {
            liElement.setAttribute("aria-expanded", "false");
            event.target.innerText = '➕';
        }

        event.preventDefault();
    }

    document.querySelector(".metadata .details").setAttribute("aria-expanded", "true");

    const splitter = document.querySelector(".splitter");

    const splitterMouseMoveHandler = (e) => {
        if (!splitter.classList.contains("hover")) return;
        
        const rect = document.body.getBoundingClientRect();
        const newLeftWidth = event.clientX - rect.left;
        const newRightWidth = rect.width - newLeftWidth - splitter.offsetWidth;

        e.preventDefault();

        if ((newLeftWidth > (0.1 * rect.width))
            && (newRightWidth > (0.1 * rect.width))) {
            const leftFraction = newLeftWidth / rect.width;
            const rightFraction = newRightWidth / rect.width;

            document.body.style.gridTemplateColumns = `${leftFraction}fr 5px ${rightFraction}fr`;
        }
    };

    const splitterMouseUpHandler = () => {
        splitter.classList.remove("hover");
        document.body.style.userSelect = "";

        document.getElementById("preview").style.pointerEvents = "auto";

        document.removeEventListener("mousemove", splitterMouseMoveHandler);
        document.removeEventListener("mouseup", splitterMouseUpHandler);
    }

    const splitterMouseDownHandler = (e) => {
        e.preventDefault();
        splitter.classList.add("hover");
        document.body.style.userSelect = "none";

        document.getElementById("preview").style.pointerEvents = "none";

        document.addEventListener("mousemove", splitterMouseMoveHandler);
        document.addEventListener("mouseup", splitterMouseUpHandler);
    }

    splitter.addEventListener("mousedown", splitterMouseDownHandler);

    document.getElementById("preview").addEventListener("load",
        (e) => {
            const path = e.target.contentWindow.location.pathname;
            if (path === undefined) return;

            const treeElement = document.querySelector(`#navigation [data-path="${path}"]`);
            setTimeout(() => {
                treeElement.classList.remove("highlighted")
            }, 2500);
            let parent = treeElement.closest("li");
            for (;;) {
                if (parent === null) break;
                parent.setAttribute("aria-expanded", "true");
                console.trace(parent);

                if (parent.parentElement === undefined) break;
                parent = parent.parentElement.closest("li");
            }
            treeElement.classList.add("highlighted");
            treeElement.scrollIntoView({
                behavior:"smooth"
            });

            showDetails(path);
        });
    </script>
</html>