export default {

    _meta: {
        size: 'large',
        escape: true
    },

    data() {
        return {
            uid: `autopilit:chat:${App.utils.nanoid()}`,
            messages: [
                {
                    role: null,
                    content: 'Hi there 👋 I\'m your AI workmate. How can I help?'
                }
            ],
            prompt: '',
            loading: false,

            progress: null,
            progressIdle: null,

            markdown: null
        }
    },

    computed: {
        chat() {
            return this.messages.filter(msg => msg !== 'system')
        }
    },

    mounted() {

        App.assets.require([
            'autopilot:assets/vendor/showdown.js',
            'autopilot:assets/vendor/highlight/highlight.min.js',
            'autopilot:assets/css/chat.css',
        ]).then(() => {

            showdown.extension('highlight', function () {
                return [{
                    type: 'output',
                    filter: function (text, converter, options) {
                        var left = "<pre><code\\b[^>]*>",
                            right = "</code></pre>",
                            flags = "g";

                        var replacement = function (wholeMatch, match, left, right) {

                            var lang = (left.match(/class=\"([^ \"]+)/) || [])[1];

                            // Decode HTML entities
                            var code = match
                                .replace(/&lt;/g, '<')
                                .replace(/&gt;/g, '>')
                                .replace(/&amp;/g, '&')
                                .replace(/&quot;/g, '"')
                                .replace(/&#39;/g, "'");

                            var highlighted;

                            try {
                                if (lang && hljs.getLanguage(lang)) {
                                    highlighted = hljs.highlight(lang, code).value;
                                } else {
                                    highlighted = hljs.highlightAuto(code).value;
                                }
                            } catch (e) {
                                highlighted = match; // Fallback
                            }

                            var langLabel = lang ? lang : 'text';

                            return `
<div class="code-block">
    <div class="code-header">
        <span class="language-label">${langLabel}</span>
        <button class="copy-btn" onclick="
            const btn = this;
            const code = btn.closest('.code-block').querySelector('code').innerText;
            navigator.clipboard.writeText(code).then(function() {
                const original = btn.innerText;
                btn.innerText = 'Copied!';
                setTimeout(function() { btn.innerText = original; }, 2000);
            }).catch(function(err) { console.error('Copy failed', err); });
        ">Copy</button>
    </div>
    <pre><code class="hljs ${langLabel}">${highlighted}</code></pre>
</div>`;
                        };
                        return showdown.helper.replaceRecursiveRegExp(text, replacement, left, right, flags);
                    }
                }];
            });

            this.markdown = new showdown.Converter({
                extensions: ['highlight'],
                requireSpaceBeforeHeadingText: true,
                tables: true,
                strikethrough: true,
                tasklists: true,
                underline: false,
            });
        })
    },

    methods: {

        send(evt) {

            if (evt && evt.shiftKey) {
                return;
            }

            if (!this.prompt.trim()) {
                return;
            }

            if (this.progressIdle) {
                clearInterval(this.progressIdle);
            }

            let message = {
                role: 'user',
                content: this.prompt
            };

            this.messages.push(message);
            this.progress = '';
            this.loading = true;

            this.$request('/autopilot/chat', { uid: this.uid, messages: this.messages.filter(msg => msg.role) }, 'text').then(message => {

                if (!message) {
                    return;
                }

                this.messages.push({
                    role: 'assistant',
                    content: message
                });

                setTimeout(() => {

                    this.$refs.chatbox.children[this.messages.length - 1].scrollIntoView({
                        behavior: 'smooth',
                        block: 'start'
                    });

                }, 50)
            }).catch(rsp => {

                if (typeof (rsp) === 'string') {

                    try {
                        rsp = JSON.parse(rsp);
                    } catch (e) { }
                }

                this.messages.push({
                    role: null,
                    content: rsp.error || 'Something went wrong',
                    type: 'error'
                });

                console.error(rsp)
            }).finally(() => {
                clearInterval(this.progressIdle);
                this.loading = false;
            });

            setTimeout(() => {
                this.$refs.chatbox.scrollTop = this.$refs.chatbox.scrollHeight;
                this.prompt = '';
            }, 20);

            this.progressIdle = setInterval(() => {

                this.$request(`/autopilot/progress`, { uid: this.uid }).then(progress => {

                    this.progress = progress.content;

                    if (this.progress) {

                        setTimeout(() => {

                            this.$refs.chatbox.children[this.$refs.chatbox.children.length - 1].scrollIntoView({
                                behavior: 'smooth',
                                block: 'end'
                            });
                        }, 20);
                    }
                });

            }, 5000);

        },

        copy(message) {
            App.utils.copyText(message.content, () => {
                App.ui.notify('Message content copied to clipboard');
            });
        },

        toMarkdown(text) {

            text = text.trim();

            // add ending code block tags when missing
            let code_block_count = (text.match(/```/g) || []).length;
            if (code_block_count % 2 !== 0) {
                text += "\n```";
            }

            return this.markdown.makeHtml(text);
        }
    },

    template: /*html*/`
    <div>
        <div class="kiss-flex kiss-flex-middle">
            <div>
                <kiss-svg class="kiss-color-primary" :src="$baseUrl('autopilot:icon.svg')" width="50" height="50"></kiss-svg>
            </div>
            <div class="kiss-flex-1 kiss-margin-start">
                <span class="kiss-size-xsmall kiss-color-muted kiss-text-upper">Autopilot</span>
                <kiss-row class="kiss-flex-middle">
                    <div class="kiss-size-4 kiss-flex-1">
                        <strong class="kiss-text-capitalize">{{ t('Workmate') }}</strong>
                    </div>
                </kiss-row>
            </div>
            <button type="button" :aria-label="t('Close')" class="kiss-input-blank kiss-cursor-pointer" kiss-dialog-close>
                <kiss-svg class="kiss-color-muted" :src="$baseUrl('system:assets/icons/close.svg')" width="15"><canvas width="15" height="15"></canvas></kiss-svg>
            </button>
        </div>
        <div class="autopilot-chatbox kiss-position-relative kiss-dialog-overflow kiss-margin" expand="true" ref="chatbox">

            <div class="kiss-cover kiss-flex kiss-flex-middle kiss-flex-center" v-if="!chat.length">
                <div class="kiss-color-muted kiss-size-xlarge">Chat</div>
            </div>

            <kiss-card class="kiss-flex kiss-padding-small" :class="{'kiss-text-monospace': msg.role !== 'user'}" :data-idx="idx" :theme="msg.role === 'user' ? 'shadowed contrast':''" gap="small" v-for="(msg, idx) in chat">
                <div class="kiss-color-muted">
                    <app-avatar size="30" :name="App.user.name" v-if="msg.role === 'user'"></app-avatar>
                    <kiss-svg :class="{'kiss-color-danger': msg.type == 'error'}" :src="$baseUrl('autopilot:icon.svg')" width="30" v-else><canvas width="30" height="30"></canvas></kiss-svg>
                </div>

                <div v-if="msg.role === 'user'" class="kiss-flex-1 kiss-size-small kiss-text-bold kiss-padding-small">{{ msg.content }}</div>
                <div v-else class="kiss-flex-1 kiss-size-small kiss-padding-small">
                    <div class="kiss-text-upper kiss-size-xsmall kiss-color-muted kiss-margin-small" v-if="msg.type == 'error'">Error</div>
                    <div v-html="markdown ? toMarkdown(msg.content) : msg.content"></div>
                </div>

                <div v-if="idx && msg.role !== 'user'">
                    <a @click="copy(msg)"><icon>content_copy</icon></a>
                </div>
            </kiss-card>

            <kiss-card class="kiss-flex kiss-padding-small" v-if="loading && progress">
                <div>
                    <kiss-svg class="kiss-color-muted" :src="$baseUrl('autopilot:icon.svg')" width="30"><canvas width="30" height="30"></canvas></kiss-svg>
                </div>
                <div class="kiss-flex-1 kiss-size-small kiss-text-light kiss-padding-small kiss-color-muted" v-html="toMarkdown(progress)"></div>
            </kiss-card>

            <div class="kiss-color-muted" v-if="loading"><app-loader mode="dots"></app-loader></div>

        </div>
        <div class="kiss-margin" :class="{'kiss-disabled': loading}">
            <kiss-card class="kiss-flex kiss-flex-middle kiss-padding-small" theme="shadowed contrast" gap>
                <textarea autofocus class="kiss-input-blank kiss-flex-1" style="height:60px;max-height:150px;resize: none;" :placeholder="t('Send a message')" v-model="prompt" @keydown.enter="send"></textarea>
                <button class="kiss-input-blank kiss-cursor-pointer" @click="send()">
                    <kiss-svg :class="{'kiss-color-muted': !prompt.trim()}" :src="$baseUrl('autopilot:assets/icons/send.svg')" width="30" height="30"><canvas width="30" height="30"></canvas></kiss-svg>
                </button>
            </kiss-card>
        </div>
    </div>
    `


}
