/* global askagentoAiChatbotFront, pfChatbotReplyFormat, pfAiChatbotEmbed */
(function () {
    'use strict';

    document.addEventListener('DOMContentLoaded', function () {
        document.querySelectorAll('[data-askagento-chatbot-root]').forEach(function (root) {
            bindChatbot(root);
        });
    });

    function mergeConfig() {
        var base = typeof askagentoAiChatbotFront !== 'undefined' ? askagentoAiChatbotFront : {};
        var embed = typeof pfAiChatbotEmbed !== 'undefined' && pfAiChatbotEmbed && typeof pfAiChatbotEmbed === 'object'
            ? pfAiChatbotEmbed
            : {};

        var cfg = {};
        var key;

        for (key in base) {
            if (Object.prototype.hasOwnProperty.call(base, key)) {
                cfg[key] = base[key];
            }
        }

        for (key in embed) {
            if (Object.prototype.hasOwnProperty.call(embed, key)) {
                cfg[key] = embed[key];
            }
        }

        return cfg;
    }

    function bindChatbot(root) {
        var cfg = mergeConfig();

        if (!cfg.chatbotUrl || !cfg.siteId || !cfg.apiKey) {
            return;
        }

        var mode = root.getAttribute('data-askagento-chatbot-mode') || 'inline';
        var isBubble = mode === 'bubble';

        if (cfg.bubbleColor) {
            root.style.setProperty('--askagento-chatbot-accent', String(cfg.bubbleColor));
        }

        var fab = root.querySelector('.askagento-chatbot-fab');
        var panel = root.querySelector('.askagento-chatbot-panel');
        var closeBtn = root.querySelector('.askagento-chatbot-panel__close');
        var messagesEl = isBubble
            ? root.querySelector('.askagento-chatbot-panel .askagento-chatbot-messages')
            : root.querySelector('.askagento-chatbot-messages');
        var input = root.querySelector('.askagento-chatbot-input');
        var sendBtn = root.querySelector('.askagento-chatbot-send');
        var statusEl = root.querySelector('.askagento-chatbot-status');
        var titleEl = root.querySelector('.askagento-chatbot-panel__title');

        if (!messagesEl || !input || !sendBtn) {
            return;
        }

        if (titleEl && cfg.panelTitle) {
            titleEl.textContent = String(cfg.panelTitle);
        }

        if (cfg.i18n && cfg.i18n.placeholder) {
            input.placeholder = String(cfg.i18n.placeholder);
        }

        var history = [];
        var opened = !isBubble;
        var welcome = cfg.welcomeMessage != null ? String(cfg.welcomeMessage).trim() : '';
        var catalog = Array.isArray(cfg.catalog) ? cfg.catalog : [];

        function i18n(key, fallback) {
            return cfg.i18n && cfg.i18n[key] ? String(cfg.i18n[key]) : (fallback || '');
        }

        function escapeHtml(str) {
            return String(str == null ? '' : str)
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;');
        }

        function mapError(msg) {
            var m = String(msg || '').trim();

            if (m === 'AI token quota exceeded') {
                return i18n('aiTokenQuotaExceeded', m);
            }

            if (m === 'AI search quota exceeded') {
                return i18n('aiSearchQuotaExceeded', m);
            }

            return m || i18n('error', 'Something went wrong.');
        }

        function setOpen(on) {
            if (!isBubble || !panel) {
                return;
            }

            opened = on;
            panel.hidden = !on;

            if (fab) {
                fab.setAttribute('aria-expanded', on ? 'true' : 'false');
            }

            root.classList.toggle('askagento-chatbot-root--open', on);

            if (on) {
                ensureWelcome();
                input.focus();
            }
        }

        function setLoading(on) {
            root.classList.toggle('askagento-chatbot-loading', on);
            sendBtn.disabled = on;
            input.disabled = on;
        }

        function scrollToBottom() {
            messagesEl.scrollTop = messagesEl.scrollHeight;
        }

        function formatAssistantContent(text) {
            if (
                typeof pfChatbotReplyFormat !== 'undefined' &&
                pfChatbotReplyFormat &&
                typeof pfChatbotReplyFormat.formatAssistantHtml === 'function'
            ) {
                return pfChatbotReplyFormat.formatAssistantHtml(text, catalog);
            }

            return escapeHtml(text).replace(/\n/g, '<br>');
        }

        function appendMessage(role, text) {
            var row = document.createElement('div');
            row.className = 'askagento-chatbot-msg askagento-chatbot-msg--' + role;

            var bubble = document.createElement('div');
            bubble.className = 'askagento-chatbot-bubble';

            if (role === 'assistant') {
                bubble.className += ' askagento-chatbot-bubble--rich';
                bubble.innerHTML = formatAssistantContent(text);
                enrichProductImages(bubble);
            } else {
                bubble.innerHTML = escapeHtml(text).replace(/\n/g, '<br>');
            }

            row.appendChild(bubble);
            messagesEl.appendChild(row);
            scrollToBottom();

            return row;
        }

        // Fill product-card thumbnails (and links) the reply references but the
        // local catalogue index doesn't cover. One batched, exact-title DB lookup
        // for all cards (fast).
        function enrichProductImages(scope) {
            if (!scope || !cfg.ajaxUrl || !cfg.textSearchNonce) {
                return;
            }

            var cards = scope.querySelectorAll('.askagento-chatbot-product[data-enrich-title]');

            if (!cards.length) {
                return;
            }

            var byTitle = {};

            Array.prototype.forEach.call(cards, function (card) {
                var t = card.getAttribute('data-enrich-title') || '';

                if (!t) {
                    return;
                }

                (byTitle[t] = byTitle[t] || []).push(card);
            });

            var titles = Object.keys(byTitle);

            if (!titles.length) {
                return;
            }

            var fd = new FormData();
            fd.append('action', 'askagento_ai_chatbot_resolve');
            fd.append('nonce', cfg.textSearchNonce);
            fd.append('titles', JSON.stringify(titles));

            fetch(cfg.ajaxUrl, { method: 'POST', body: fd })
                .then(function (r) { return r.json(); })
                .then(function (data) {
                    if (!data || !data.success || !data.data) {
                        return;
                    }

                    var rows = Array.isArray(data.data.results) ? data.data.results : [];

                    rows.forEach(function (row) {
                        var matchCards = byTitle[row.title];

                        if (!matchCards) {
                            return;
                        }

                        var imgUrl = row.image_url ? String(row.image_url).trim() : '';
                        var link = row.permalink ? String(row.permalink) : '';

                        matchCards.forEach(function (card) {
                            if (imgUrl) {
                                var ph = card.querySelector('.askagento-chatbot-product__img--empty');

                                if (ph) {
                                    var im = document.createElement('img');
                                    im.className = 'askagento-chatbot-product__img';
                                    im.src = imgUrl;
                                    im.alt = '';
                                    im.loading = 'lazy';
                                    im.decoding = 'async';
                                    ph.replaceWith(im);
                                }
                            }

                            if (link) {
                                var titleEl = card.querySelector('.askagento-chatbot-product__title');

                                if (titleEl && !titleEl.querySelector('a')) {
                                    var a = document.createElement('a');
                                    a.href = link;
                                    a.textContent = titleEl.textContent;
                                    titleEl.textContent = '';
                                    titleEl.appendChild(a);
                                }
                            }

                            card.removeAttribute('data-enrich-title');
                        });
                    });
                })
                .catch(function () {
                    /* leave placeholder on failure */
                });
        }

        function appendTyping() {
            var row = document.createElement('div');
            row.className = 'askagento-chatbot-msg askagento-chatbot-msg--assistant';

            var bubble = document.createElement('div');
            bubble.className = 'askagento-chatbot-bubble';
            bubble.innerHTML =
                '<span class="askagento-chatbot-dots" aria-label="' + escapeHtml(i18n('thinking', 'Thinking')) + '">' +
                '<span></span><span></span><span></span>' +
                '</span>';

            row.appendChild(bubble);
            messagesEl.appendChild(row);
            scrollToBottom();

            return row;
        }

        function autoResize() {
            input.style.height = 'auto';
            input.style.height = Math.min(input.scrollHeight, 140) + 'px';
        }

        function ensureWelcome() {
            if (!welcome || messagesEl.querySelector('.askagento-chatbot-msg')) {
                return;
            }

            appendMessage('assistant', welcome);
        }

        function send() {
            var text = (input.value || '').trim();

            if (!text) {
                return;
            }

            if (statusEl) {
                statusEl.textContent = '';
            }

            input.value = '';
            autoResize();

            appendMessage('user', text);
            history.push({ role: 'user', content: text });

            setLoading(true);

            var typingRow = appendTyping();

            fetch(cfg.chatbotUrl, {
                method: 'POST',
                headers: {
                    'Content-Type':        'application/json',
                    'X-Askagento-Site-Id': cfg.siteId,
                    'X-Askagento-Api-Key': cfg.apiKey,
                },
                body: JSON.stringify({
                    action:                'chat',
                    messages:              history,
                    max_completion_tokens: 2048,
                }),
            })
                .then(function (res) {
                    return res.json().then(function (data) {
                        return { ok: res.ok, status: res.status, data: data };
                    });
                })
                .then(function (payload) {
                    typingRow.remove();

                    if (!payload.ok) {
                        var remoteErr =
                            payload.data && typeof payload.data.error === 'string'
                                ? payload.data.error
                                : 'HTTP ' + String(payload.status);

                        throw new Error(remoteErr);
                    }

                    var reply = payload.data.reply != null ? String(payload.data.reply) : '';

                    if (!reply) {
                        reply = i18n('error', 'No response received.');
                    }

                    appendMessage('assistant', reply);
                    history.push({ role: 'assistant', content: reply });
                })
                .catch(function (err) {
                    typingRow.remove();

                    if (statusEl) {
                        statusEl.textContent = mapError(err && err.message ? err.message : '');
                    }
                })
                .finally(function () {
                    setLoading(false);
                    input.focus();
                });
        }

        if (isBubble) {
            if (fab) {
                fab.addEventListener('click', function () {
                    setOpen(!opened);
                });
            }

            if (closeBtn) {
                closeBtn.addEventListener('click', function () {
                    setOpen(false);
                });
            }

            document.addEventListener('keydown', function (e) {
                if (e.key === 'Escape' && opened) {
                    setOpen(false);
                }
            });
        } else {
            ensureWelcome();
        }

        sendBtn.addEventListener('click', send);
        input.addEventListener('input', autoResize);
        input.addEventListener('keydown', function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                send();
            }
        });
    }
})();
