import XNode from "@web-atoms/core/dist/core/XNode";
import { AtomControl } from "@web-atoms/core/dist/web/controls/AtomControl";
import { ContentPage, isMobileView } from "@web-atoms/web-controls/dist/mobile-app/MobileApp";
import { UMD } from "@web-atoms/core/dist/core/types";
import WebApp from "@web-atoms/core/dist/web/WebApp";
import styled from "@web-atoms/core/dist/style/styled";
import AnimatedLoader from "../../controls/AnimatedLoader";
import Action from "@web-atoms/core/dist/view-model/Action";

(UMD as any).map("showdown", "https://cdn.jsdelivr.net/npm/showdown@1.9.0/");

const css = styled.css `
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 5px;
    overflow: hidden;
    & > .md {
        overflow: auto;
        align-self: stretch;
        justify-self: stretch;

        & pre {
            border: solid 1px lightgray;
        }
    }
    & > .index {
        width: 200px;
        align-self: stretch;
        overflow: auto;
        & > * {
            margin: 5px;
            cursor: pointer;
            color: var(--link-color, blue);
            &:hover {
                text-decoration: underline;
            }
        }
    }
`.installLocal();

let nextHeaderId = 1;

declare let System: any;

export default class MDPage extends ContentPage<{url: string; label: string;}> {

    public index: HTMLDivElement;

    public async init() {

        this.title = this.parameters.label;

        this.renderer = <AnimatedLoader/>;

        const rs = await fetch( System.resolve(this.parameters.url));
        const code = await rs.text();

        if (rs.status > 300) {
            this.renderer = <div>
                <h4>Failed to load {this.parameters.url}</h4>
                <p>
                    {code}
                </p>
            </div>;
            return;
        }

        this.renderer = <div class={css}>
            <div class="md"></div>
            {!isMobileView && <div class="index"></div>}
        </div>;

        this.index = this.element.querySelector(".index");

        await this.loadCode(code);

    }

    @Action({ onEvent: "show-header"})
    showHeader({ headerId }) {
        const e = this.element.querySelector(`#${headerId}`);
        e.scrollIntoView();
    }

    async loadCode(code: string) {
        const app = this.app as WebApp;
        app.installStyleSheet("https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github.min.css");


        const showdown = await UMD.import<any>("showdown/dist/showdown.js");

        const text = code;

        const converter = new showdown.Converter();
        converter.setOption("openLinksInNewWindow",true);
        converter.setOption("simplifiedAutoLink", true);
        const element = this.element;

        const mdRoot = element.querySelector(".md");

        const md = document.createElement("div");

        md.innerHTML = converter.makeHtml(text);
        md.style.width = "100%";
        md.style.height = "100%";
        md.className = "page";

        mdRoot.appendChild(md);

        setTimeout(() => {
            this.findHeader(md);
        }, 100);

        await UMD.import<any>("https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/highlight.min.js");

        const highlight = (window as any).hljs;

        const all = document.querySelectorAll("pre > code");
        // tslint:disable-next-line:prefer-for-of
        for (let index = 0; index < all.length; index++) {
            const e = all[index];
            highlight.highlightBlock(e);
        }

        for(const iterator of Array.from(this.element.querySelectorAll("a"))) {
            if(/^(http|https)\:\/\//) {
                iterator.target = "_blank";
            }
        }
    }

    private findHeader(e: HTMLElement): void {
        if (!e) {
            return;
        }
        const all = Array.from(e.querySelectorAll("h1,h2,h3,h4,h5,h6"));
        const index = this.index;
        for (const iterator of all) {
            const id = iterator.id ||= `nh-${nextHeaderId++}`;
            const link = document.createElement("div");
            link.className = "header"
            link.textContent = iterator.textContent;
            link.style.paddingLeft = `${parseFloat(iterator.tagName.substring(1)) * 5}px`;
            link.setAttribute("data-click-event", "show-header");
            link.setAttribute("data-header-id", id);
            index.appendChild(link);
        }
    }

}
