import { marked } from 'marked';
import TurndownService from 'turndown';
import { gfm } from 'turndown-plugin-gfm';

const turndown = new TurndownService({
    headingStyle: 'atx',
    codeBlockStyle: 'fenced',
    bulletListMarker: '-',
});

turndown.use(gfm);

turndown.addRule('kbCallout', {
    filter: (node) =>
        node.nodeName === 'ASIDE' && Boolean(node.getAttribute('data-callout')),
    replacement: (_content, node) => {
        const aside = node as HTMLElement;
        const variant = aside.getAttribute('data-callout') || 'note';
        const clone = aside.cloneNode(true) as HTMLElement;
        clone.querySelector('.kb-callout-title')?.remove();
        const inner = turndown.turndown(clone.innerHTML).trim();

        return `\n\n:::${variant}\n${inner}\n:::\n\n`;
    },
});

turndown.addRule('kbYoutube', {
    filter: (node) => {
        if (node.nodeName === 'IFRAME') {
            return /youtube(-nocookie)?\.com\/embed\//.test(
                (node as HTMLIFrameElement).src || '',
            );
        }

        return (
            node.nodeName === 'DIV' &&
            (node.hasAttribute('data-youtube-video') ||
                node.classList.contains('kb-embed'))
        );
    },
    replacement: (_content, node) => {
        const iframe =
            node.nodeName === 'IFRAME'
                ? (node as HTMLIFrameElement)
                : (node as HTMLElement).querySelector('iframe');
        const src = iframe?.getAttribute('src') || '';
        const id = src.match(/embed\/([A-Za-z0-9_-]+)/)?.[1];

        return id ? `\n\n@[youtube](${id})\n\n` : '';
    },
});

export function markdownToHtml(markdown: string): string {
    let src = markdown;

    src = src.replace(
        /^:::(note|tip|warning|danger)[ \t]*\n([\s\S]*?)\n:::[ \t]*$/gm,
        (_full, variant: string, body: string) => {
            const inner = marked.parse(body, { async: false }) as string;

            return `<aside data-callout="${variant}" class="kb-callout kb-callout-${variant}">${inner}</aside>`;
        },
    );

    src = src.replace(
        /@\[youtube\]\(([A-Za-z0-9_-]+)\)/g,
        (_full, id: string) =>
            `<div data-youtube-video=""><iframe src="https://www.youtube-nocookie.com/embed/${id}"></iframe></div>`,
    );

    return marked.parse(src, { async: false }) as string;
}

export function htmlToMarkdown(html: string): string {
    return turndown.turndown(html).trim();
}
