(function () {
    'use strict';

    var thread = document.getElementById('msgThread');
    var composer = document.getElementById('msgComposer');
    var messagesEl = document.getElementById('msgMessages');
    var bodyInput = document.getElementById('msgBody');

    if (!thread || !composer || !messagesEl) {
        return;
    }

    var conversationId = thread.getAttribute('data-conversation-id');
    var currentUserId = parseInt(thread.getAttribute('data-user-id') || '0', 10);
    var lastId = parseInt(composer.getAttribute('data-last-id') || '0', 10);
    var sendUrl = composer.getAttribute('action');
    var pollUrl = sendUrl.replace(/\/send$/, '/poll');

    function getCookie(name) {
        var match = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1') + '=([^;]*)'));
        return match ? decodeURIComponent(match[1]) : '';
    }

    function csrfToken() {
        var input = composer.querySelector('input[name="csrf_test_name"]');
        var fromCookie = getCookie('csrf_cookie_name');
        if (fromCookie) {
            if (input) {
                input.value = fromCookie;
            }
            return fromCookie;
        }
        return input ? input.value : '';
    }

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

    function escapeHtml(str) {
        var div = document.createElement('div');
        div.textContent = str;
        return div.innerHTML;
    }

    function formatTime(iso) {
        try {
            var d = new Date(String(iso).replace(' ', 'T'));
            return d.toLocaleString(undefined, {
                month: 'short',
                day: 'numeric',
                hour: 'numeric',
                minute: '2-digit'
            });
        } catch (e) {
            return iso;
        }
    }

    function appendMessage(msg) {
        if (!msg || !msg.id) {
            return;
        }
        if (messagesEl.querySelector('[data-message-id="' + msg.id + '"]')) {
            return;
        }

        var mine = !!msg.is_mine || msg.sender_id === currentUserId;
        var el = document.createElement('div');
        el.className = 'msg-bubble' + (mine ? ' msg-bubble--mine' : '');
        el.setAttribute('data-message-id', String(msg.id));

        var html = '';
        if (!mine) {
            html += '<div class="msg-bubble__sender">' + escapeHtml(msg.sender || 'User') + '</div>';
        }
        html += '<div class="msg-bubble__body">' + escapeHtml(msg.body || '').replace(/\n/g, '<br>') + '</div>';
        html += '<div class="msg-bubble__time">' + escapeHtml(formatTime(msg.created_at || '')) + '</div>';
        el.innerHTML = html;
        messagesEl.appendChild(el);

        if (msg.id > lastId) {
            lastId = msg.id;
        }
    }

    function poll() {
        if (!conversationId || conversationId === '0') {
            return;
        }

        var url = pollUrl + '?after=' + encodeURIComponent(String(lastId));
        fetch(url, {
            headers: { 'Accept': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
            credentials: 'same-origin'
        })
            .then(function (r) { return r.json(); })
            .then(function (data) {
                if (!data || !data.success || !data.messages) {
                    return;
                }
                var added = false;
                data.messages.forEach(function (m) {
                    appendMessage(m);
                    added = true;
                });
                if (added) {
                    scrollToBottom();
                }
            })
            .catch(function () { /* ignore transient poll errors */ });
    }

    composer.addEventListener('submit', function (e) {
        e.preventDefault();
        var body = (bodyInput.value || '').trim();
        if (!body) {
            return;
        }

        var token = csrfToken();
        var formData = new FormData();
        formData.append('body', body);
        formData.append('csrf_test_name', token);

        var btn = composer.querySelector('button[type="submit"]');
        if (btn) {
            btn.disabled = true;
        }

        fetch(sendUrl, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-TOKEN': token
            },
            body: formData,
            credentials: 'same-origin'
        })
            .then(function (r) { return r.json().then(function (j) { return { ok: r.ok, json: j }; }); })
            .then(function (res) {
                if (btn) {
                    btn.disabled = false;
                }
                if (!res.ok || !res.json.success) {
                    alert((res.json && res.json.error) || 'Could not send message.');
                    return;
                }
                bodyInput.value = '';
                csrfToken();
                appendMessage(res.json.message);
                scrollToBottom();
            })
            .catch(function () {
                if (btn) {
                    btn.disabled = false;
                }
                composer.submit();
            });
    });

    bodyInput.addEventListener('keydown', function (e) {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            composer.dispatchEvent(new Event('submit', { cancelable: true }));
        }
    });

    scrollToBottom();
    setInterval(poll, 4000);
})();
