// Page script for sendMessage.html. Bootstrapping (auth cookie check, /info
// fetch, header rendering, active-nav highlight) all live in js/app.js;
// this file just wires the compose form.

var modal = document.querySelector('.modal');
var overlay = document.querySelector('.overlay');

var message = new EasyMDE({
    element: document.getElementById('my-text-area'),
    toolbar: [
        'bold', 'italic', '|',
        'heading-1', 'heading-2', 'heading-3', '|',
        'code', 'unordered-list', 'ordered-list', 'link', 'quote', '|',
        'preview'
    ],
    maxHeight: '260px',
});

// In-memory mirror of the server-side favorites list for this user + bot.
// Kept in sync with every /user/groups/add and /user/groups/remove response
// so the chip strip and the "already a favorite?" check stay authoritative
// without a round-trip.
var favoriteGroups = [];

CollabCentral.init(function (ctx) {
    // User is authenticated and authorized. Reveal the form + populate the
    // group selectors from the backend.
    document.getElementById('formPanel').classList.remove('hidden');
    loadFavoriteGroups(ctx.appName);
    loadNewGroups(ctx.appName);
});

document.getElementById('sendMessage').onsubmit = function (event) {
    event.preventDefault();
    var appName = CollabCentral.appName;
    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function () {
        if (this.readyState === this.DONE && this.status === 200) {
            var result = JSON.parse(xhttp.response);
            var scheduled = document.getElementById('scheduledFor').value;
            var text = 'This message will be sent to <strong>' + result.memberList.length + '</strong> recipient(s).<br><br>';
            if (scheduled) {
                text += 'Scheduled for ' + CollabCentral.escapeHtml(scheduled) + '.';
            } else {
                text += 'It will be sent immediately once you confirm.';
            }
            document.getElementById('modalMessage').innerHTML = text;
            openModal();
        }
    };

    var formData = new FormData();
    formData.append('uploadImage', document.getElementById('uploadImage').files[0]);
    formData.append('message', message.value());
    formData.append('uploadCSV', document.getElementById('uploadCSV').files[0]);
    formData.append('appName', appName);

    var selectedGroups = [];
    for (var group of document.querySelector('#favGroups').getSelectedOptions()) {
        selectedGroups.push(group.value);
    }
    for (var group of document.querySelector('#newGroups').getSelectedOptions()) {
        selectedGroups.push(group.value);
    }
    formData.append('groups', selectedGroups);
    formData.append('scheduledFor', document.getElementById('scheduledFor').value);

    xhttp.open('POST', '/CollabCentral/' + appName + '/jobs/edit');
    xhttp.send(formData);
};

function showImagePreview(event) {
    if (!event.target.files || !event.target.files.length) return;
    var src = URL.createObjectURL(event.target.files[0]);
    var preview = document.getElementById('file-ip-1-preview');
    preview.src = src;
    preview.style.display = 'block';
}

// ---- Favorites -----------------------------------------------------------

function loadFavoriteGroups(appName) {
    var el = document.getElementById('favGroups');
    fetch('/CollabCentral/' + appName + '/user/groups/list')
        .then(function (res) { return res.json(); })
        .then(function (groups) {
            favoriteGroups = Array.isArray(groups) ? groups.slice() : [];
            for (var i = 0; i < favoriteGroups.length; i++) {
                var option = document.createElement('option');
                option.text = favoriteGroups[i].name;
                option.value = favoriteGroups[i].id;
                el.add(option);
            }
            VirtualSelect.init({ ele: '#favGroups' });
            renderFavoritesManager();
        });
}

// Renders the chip strip below the favorites picker. Each chip has an
// × button that removes the group from favorites. The chip strip is
// intentionally separate from the VirtualSelect widget: the picker answers
// "which favorites am I sending to right now?", the chip strip answers
// "which groups do I want to remember for next time?".
function renderFavoritesManager() {
    var el = document.getElementById('favGroupsManager');
    if (!el) return;
    el.innerHTML = '';
    if (!favoriteGroups.length) {
        el.classList.add('hidden');
        return;
    }
    el.classList.remove('hidden');
    for (var i = 0; i < favoriteGroups.length; i++) {
        var g = favoriteGroups[i];
        var chip = document.createElement('span');
        chip.className = 'chip';
        var label = document.createElement('span');
        label.className = 'chip__label';
        label.textContent = g.alias ? g.alias : g.name;
        if (g.alias && g.name && g.alias !== g.name) {
            chip.title = g.name;
        }
        var btn = document.createElement('button');
        btn.type = 'button';
        btn.className = 'chip__close';
        btn.setAttribute('aria-label', 'Remove ' + (g.name || 'favorite'));
        btn.textContent = '×';
        btn.dataset.groupId = g.id;
        btn.addEventListener('click', onRemoveFavorite);
        chip.appendChild(label);
        chip.appendChild(btn);
        el.appendChild(chip);
    }
}

function onRemoveFavorite(event) {
    var groupId = event.currentTarget.dataset.groupId;
    if (!groupId) return;
    event.currentTarget.disabled = true;
    fetch('/CollabCentral/' + CollabCentral.appName + '/user/groups/remove', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id: groupId })
    })
        .then(function (res) {
            if (!res.ok) throw new Error('HTTP ' + res.status);
            return res.json();
        })
        .then(function (updatedFavorites) {
            favoriteGroups = updatedFavorites || [];
            renderFavoritesManager();
            flashFavoritesStatus('Removed from favorites.');
        })
        .catch(function (err) {
            console.error('Failed to remove favorite:', err);
            flashFavoritesStatus('Could not remove favorite.', true);
            event.currentTarget.disabled = false;
        });
}

// Fires when the "Additional groups" multi-select changes. For each newly
// selected id that isn't already a favorite we POST /user/groups/add. The
// picker itself keeps the selection (so this send still uses the group);
// the group starts appearing in the Favorite Groups picker on the next
// page load, and immediately in the chip strip below.
function onNewGroupsChange(newlySelectedIds) {
    if (!newlySelectedIds || !newlySelectedIds.length) return;
    var newGroupsEl = document.getElementById('newGroups');
    var pending = 0;
    var successes = 0;

    newlySelectedIds.forEach(function (id) {
        if (favoriteGroups.some(function (g) { return g.id === id; })) return;
        pending++;
        fetch('/CollabCentral/' + CollabCentral.appName + '/user/groups/add', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ id: id })
        })
            .then(function (res) {
                if (!res.ok) throw new Error('HTTP ' + res.status);
                return res.json();
            })
            .then(function (updatedFavorites) {
                favoriteGroups = updatedFavorites || favoriteGroups;
                successes++;
                renderFavoritesManager();
            })
            .catch(function (err) {
                console.error('Failed to add favorite ' + id + ':', err);
                flashFavoritesStatus('Could not save one or more favorites.', true);
            })
            .finally(function () {
                pending--;
                if (pending === 0 && successes > 0) {
                    flashFavoritesStatus(successes === 1
                        ? 'Added to favorites.'
                        : 'Added ' + successes + ' to favorites.');
                }
            });
    });
}

function flashFavoritesStatus(text, isError) {
    var el = document.getElementById('favGroupsStatus');
    if (!el) return;
    el.textContent = text;
    el.classList.toggle('fieldStatus--error', !!isError);
    clearTimeout(flashFavoritesStatus._t);
    flashFavoritesStatus._t = setTimeout(function () {
        el.textContent = '';
        el.classList.remove('fieldStatus--error');
    }, 4000);
}

function loadNewGroups(appName) {
    var el = document.getElementById('newGroups');
    fetch('/CollabCentral/' + appName + '/user/groups/find')
        .then(function (res) { return res.json(); })
        .then(function (groups) {
            for (var i = 0; i < groups.length; i++) {
                var option = document.createElement('option');
                option.text = groups[i].displayName;
                option.value = groups[i].id;
                el.add(option);
            }
            VirtualSelect.init({ ele: '#newGroups' });

            // VirtualSelect emits a standard 'change' event on the original
            // <select>. We diff against the previous selection so we only
            // fire /user/groups/add for the newly-picked ids, not the whole
            // set on every change.
            var previous = [];
            el.addEventListener('change', function () {
                var current = [];
                var selected = el.getSelectedOptions();
                for (var j = 0; j < selected.length; j++) current.push(selected[j].value);
                var added = current.filter(function (id) { return previous.indexOf(id) === -1; });
                previous = current;
                if (added.length) onNewGroupsChange(added);
            });
        });
}

// ---- cancel / discard -----------------------------------------------------

// POSTs /jobs/cancel to drop the caller's in-progress "building" job for
// this bot. Idempotent server-side, so it's safe to call whether or not
// the user has already hit "Review & send" (which is what creates the
// building entry). Fires an unawaited request — clearing the local form
// doesn't depend on the response.
function requestServerCancel() {
    fetch('/CollabCentral/' + CollabCentral.appName + '/jobs/cancel', { method: 'POST' })
        .catch(function (err) { console.error('Cancel request failed:', err); });
}

// Cancel button on the compose form. Confirms with the user (a stray
// click shouldn't nuke a half-written draft), tells the server to drop
// any in-progress building entry, then clears the local form.
function cancelMessage() {
    var hasDraft = !!message.value()
        || document.getElementById('uploadImage').files.length
        || document.getElementById('uploadCSV').files.length
        || document.querySelector('#favGroups').getSelectedOptions().length
        || document.querySelector('#newGroups').getSelectedOptions().length
        || document.getElementById('scheduledFor').value;
    if (hasDraft && !window.confirm('Discard this message?')) return;
    requestServerCancel();
    clearForm();
}

// "Discard" action from inside the review modal — same as Cancel but
// also closes the modal (which is open at this point).
function discardMessage() {
    requestServerCancel();
    clearForm();
    closeModal();
}

// ---- send-flow modal ------------------------------------------------------

function submit() {
    var appName = CollabCentral.appName;
    var scheduled = document.getElementById('scheduledFor').value;
    var url = scheduled
        ? '/CollabCentral/' + appName + '/jobs/schedule'
        : '/CollabCentral/' + appName + '/jobs/runNow';

    fetch(url, { method: 'POST', redirect: 'follow' })
        .then(function (response) {
            clearForm();
            if (response.redirected) window.location.href = response.url;
        })
        .catch(function (err) {
            console.error('Submit failed:', err);
        });

    closeModal();
}

function continueEditing() { closeModal(); }

function openModal() {
    modal.classList.remove('hidden');
    overlay.classList.remove('hidden');
}

function closeModal() {
    modal.classList.add('hidden');
    overlay.classList.add('hidden');
}

overlay.addEventListener('click', closeModal);

function clearForm() {
    document.getElementById('uploadImage').value = '';
    message.value('');
    document.getElementById('uploadCSV').value = '';
    document.getElementById('scheduledFor').value = '';
    var preview = document.getElementById('file-ip-1-preview');
    preview.removeAttribute('src');
    preview.style.display = 'none';
    // VirtualSelect exposes setValue([]) to clear a multi-select without
    // reinitializing the widget. Guard for the case where init hasn't run
    // yet (e.g. clearForm() called before the group lists finished loading).
    var fav = document.querySelector('#favGroups');
    if (fav && typeof fav.setValue === 'function') fav.setValue([]);
    var newG = document.querySelector('#newGroups');
    if (newG && typeof newG.setValue === 'function') newG.setValue([]);
}
