<script>
import Icon from './Icon.vue';
import spelling from '../plugins/spelling.js';
import { escapeHtml } from '../src/helpers.js';

export default {
    mixins: [spelling],
    props: {
        text: { required: true },
        noicons: { type: Boolean },
        escape: { type: Boolean },
    },
    render(h) {
        let text = this.text;
        if (this.escape) {
            text = escapeHtml(text);
        }
        if (!text) {
            return h('span');
        }

        let isLink = false;
        let isIcon = false;
        let isEscape = false;
        let buffer = '';
        let linkBuffer = '';
        const children = [];
        const buildLink = (_) => {
            if (isIcon) {
                return h(Icon, { props: { v: buffer } });
            }

            const bufferNode = [h('span', { domProps: { innerHTML: this.handleSpelling(buffer) } })];

            if (!isLink) {
                return bufferNode;
            }

            linkBuffer = linkBuffer.replace(/≡/g, '='); // meh workaround, i know…

            if (linkBuffer === '') {
                linkBuffer = `#${buffer}`;
            }

            if (linkBuffer.startsWith('https://') ||
                    linkBuffer.startsWith('http://') ||
                    linkBuffer.startsWith('mailto:') ||
                    linkBuffer.endsWith('.pdf')
            ) {
                return h(
                    'a',
                    { domProps: { href: linkBuffer, target: '_blank', rel: 'noopener' } },
                    bufferNode,
                );
            }

            if (linkBuffer.indexOf('#') === 0) {
                return h(
                    'a',
                    { domProps: { href: linkBuffer } },
                    bufferNode,
                );
            }

            return h(
                'nuxt-link',
                { props: { to: linkBuffer || `/${this.$config.nouns.route}#${this.handleSpelling(buffer)}` } },
                bufferNode,
            );
        };
        const addChild = (_) => {
            if (!buffer) {
                return;
            }
            children.push(buildLink());
            buffer = '';
            linkBuffer = '';
        };
        for (const c of text) {
            if (c === '{') {
                addChild();
                isLink = true;
                continue;
            } else if (c === '}') {
                addChild();
                isLink = false;
                continue;
            } else if (isLink && c === '=') {
                if (linkBuffer) {
                    linkBuffer += '=';
                }
                linkBuffer += buffer;
                buffer = '';
                continue;
            } else if (c === '[' && !this.noicons) {
                addChild();
                if (isEscape) {
                    isEscape = false;
                } else {
                    isIcon = true;
                    continue;
                }
            } else if (c === ']' && !this.noicons) {
                addChild();
                if (isIcon) {
                    isIcon = false;
                    continue;
                }
            } else if (c === '\\') {
                isEscape = true;
                continue;
            } else if (isEscape) {
                buffer += '\\';
                isEscape = false;
            }
            buffer += c;
        }
        addChild();

        return h('span', children);
    },
};
</script>
