let draggedItem = null;

const messageHandler = event => {
    var message = event.data.message;
    var args = event.data.args;

    switch (message) {
        case commands.MG_GET_FAVORITES:
            let entriesContainer = document.getElementById('entries-container');
            if (args.favorites.length > 0) {
                entriesContainer.textContent = '';
                let clearButton = document.getElementById('btn-clear-favorites');
                if (args.hideFavoritesButton) {
                    clearButton.classList.add('hidden');
                } else {
                    clearButton.classList.remove('hidden');
                }
            }
            loadFavorites(args.favorites, args.hideFavoritesButton);
            if (args.favorites.length == 0) {
                loadUIForEmptyFavorites();
            }
            break;
        case commands.MG_CLEAR_FAVORITES:
            toggleClearPrompt();
            loadUIForEmptyFavorites();
            break;
        default:
            console.log(`Unexpected message: ${JSON.stringify(event.data)}`);
            break;
    }
};

function requestFavorites() {
    let message = {
        message: commands.MG_GET_FAVORITES,
        args: {}
    };

    window.chrome.webview.postMessage(message);
}

function removeFavorite(uri) {
    let message = {
        message: commands.MG_REMOVE_FAVORITE,
        args: {
            uri: uri
        }
    };

    window.chrome.webview.postMessage(message);
}

function saveFavoriteOrder() {
    let containers = document.querySelectorAll('.item-container');
    let uris = Array.from(containers).map(c => c.getAttribute('data-uri'));
    let message = {
        message: commands.MG_REORDER_FAVORITES,
        args: {
            uris: uris
        }
    };
    window.chrome.webview.postMessage(message);
}

function loadFavorites(payload, hideFavoritesButton) {
    let fragment = document.createDocumentFragment();

    payload.map(favorite => {
        let favoriteContainer = document.createElement('div');
        favoriteContainer.className = 'item-container';
        favoriteContainer.setAttribute('data-uri', favorite.uri);
        favoriteContainer.draggable = true;

        favoriteContainer.addEventListener('dragstart', function(e) {
            draggedItem = this;
            this.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
        });

        favoriteContainer.addEventListener('dragend', function() {
            this.classList.remove('dragging');
            draggedItem = null;
            document.querySelectorAll('.item-container').forEach(c => c.classList.remove('drag-over'));
            saveFavoriteOrder();
        });

        favoriteContainer.addEventListener('dragover', function(e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (this !== draggedItem) {
                this.classList.add('drag-over');
            }
        });

        favoriteContainer.addEventListener('dragleave', function() {
            this.classList.remove('drag-over');
        });

        favoriteContainer.addEventListener('drop', function(e) {
            e.preventDefault();
            this.classList.remove('drag-over');
            if (draggedItem !== this) {
                let container = this.parentNode;
                let allItems = Array.from(container.children);
                let draggedIndex = allItems.indexOf(draggedItem);
                let droppedIndex = allItems.indexOf(this);
                if (draggedIndex < droppedIndex) {
                    container.insertBefore(draggedItem, this.nextSibling);
                } else {
                    container.insertBefore(draggedItem, this);
                }
            }
        });

        let dragHandle = document.createElement('div');
        dragHandle.className = 'drag-handle';
        dragHandle.textContent = '\u2630';

        let favoriteElement = document.createElement('div');
        favoriteElement.className = 'item';
        favoriteElement.addEventListener('click', function() {
            window.location.href = favorite.uri;
        });

        let faviconElement = document.createElement('div');
        faviconElement.className = 'favicon';
        let faviconImage = document.createElement('img');
        if (favorite.fileSource && favorite.uri) {
            try {
                let hostname = new URL(favorite.uri).hostname;
                faviconImage.src = 'https://www.google.com/s2/favicons?domain=' + hostname + '&sz=32';
            } catch(e) {
                faviconImage.src = favorite.favicon;
            }
        } else {
            faviconImage.src = favorite.favicon;
        }
        faviconElement.appendChild(faviconImage);

        let labelElement = document.createElement('div');
        labelElement.className = 'label-title';
        let textElement = document.createElement('span');
        textElement.textContent = favorite.title;
        textElement.title = favorite.title;
        labelElement.appendChild(textElement);

        let uriElement = document.createElement('div');
        uriElement.className = 'label-uri';
        let uriTextElement = document.createElement('p');
        uriTextElement.textContent = favorite.uriToShow || favorite.uri;
        uriTextElement.title = favorite.uriToShow || favorite.uri;
        uriElement.appendChild(uriTextElement);

        let buttonElement = document.createElement('div');
        buttonElement.className = 'btn-close';
        if (hideFavoritesButton) {
            buttonElement.style.display = 'none';
        }
        buttonElement.addEventListener('click', function(e) {
            e.stopPropagation();
            favoriteContainer.parentNode.removeChild(favoriteContainer);
            removeFavorite(favorite.uri);

            let entriesContainer = document.getElementById('entries-container');
            if (entriesContainer.childElementCount == 0) {
                loadUIForEmptyFavorites();
            }
        });

        favoriteElement.appendChild(dragHandle);
        favoriteElement.appendChild(faviconElement);
        favoriteElement.appendChild(labelElement);
        favoriteElement.appendChild(uriElement);
        favoriteElement.appendChild(buttonElement);

        favoriteContainer.appendChild(favoriteElement);
        fragment.appendChild(favoriteContainer);
    });

    let container = document.getElementById('entries-container');
    container.appendChild(fragment);
}

function loadUIForEmptyFavorites() {
    let entriesContainer = document.getElementById('entries-container');
    entriesContainer.textContent = 'You don\'t have any favorites.';

    let clearButton = document.getElementById('btn-clear-favorites');
    clearButton.classList.add('hidden');
}

function toggleClearPrompt() {
    let promptOverlay = document.getElementById('overlay');
    promptOverlay.classList.toggle('hidden');
}

function clearFavorites() {
    toggleClearPrompt();
    loadUIForEmptyFavorites();

    let message = {
        message: commands.MG_CLEAR_FAVORITES,
        args: {}
    };

    window.chrome.webview.postMessage(message);
}

function addUIListeners() {
    let confirmButton = document.getElementById('prompt-true');
    confirmButton.addEventListener('click', function(event) {
        clearFavorites();
        event.stopPropagation();
    });

    let cancelButton = document.getElementById('prompt-false');
    cancelButton.addEventListener('click', function(event) {
        toggleClearPrompt();
        event.stopPropagation();
    });

    let promptBox = document.getElementById('prompt-box');
    promptBox.addEventListener('click', function(event) {
        event.stopPropagation();
    });

    let promptOverlay = document.getElementById('overlay');
    promptOverlay.addEventListener('click', toggleClearPrompt);

    let clearButton = document.getElementById('btn-clear-favorites');
    clearButton.addEventListener('click', toggleClearPrompt);
}

function init() {
    window.chrome.webview.addEventListener('message', messageHandler);
    addUIListeners();
    requestFavorites();
}

init();
