/*
 * Handle mappings
 * Mappings are stored in local storage as a Map (key: directory)
 */
const invalidFileNameCharsRe  =/[^\\\|:\*\?"<>]/;  // dont allow \/|:*?<>
const invalidFileNameChars = "\\|:*?<>";

let statusLine = document.getElementById('status');

// these can not be mapped by the user
const reservedMappings = ["u", "s"];

/*
 * Load mappings, create a table showing them with a "remove" button each
 */
function renderMappings() {
    // console.log(localStorage.getItem('mappings'));
    const mappings = new Map(JSON.parse(localStorage.getItem('mappings')) || []);
    const tbody = document.querySelector('#mappingTable tbody');
    tbody.innerHTML = ''; // clear table body
    mappings.forEach((directory, key) => {
        const row = document.createElement('tr');
        const keyCell = document.createElement('td');
        const directoryCell = document.createElement('td');

        keyCell.innerHTML = `<span class="key">${key}</span>`;
        directoryCell.innerHTML = `<span class="path">${directory}</span>`;

        row.appendChild(keyCell);
        row.appendChild(directoryCell);
        // remove mapping button
        const removeCell = document.createElement('td');
        const removeButton = document.createElement('button');
        removeButton.textContent = 'Remove';
        removeButton.onclick = function() {
            removeMapping(key);
        };
        removeCell.appendChild(removeButton);
        row.appendChild(removeCell)
        tbody.appendChild(row);
    });
}

function removeMapping(key) {
    let mappings = new Map(JSON.parse(localStorage.getItem('mappings')) || []);
    if (!mappings.has(key)) {
        statusLine.innerHTML = `Can not remove mapping '${key}', it does not exist`;
        return;
    }
    statusLine.innerHTML = `Removed mapping '${key}'`;
    mappings.delete(key);
    localStorage.setItem('mappings', JSON.stringify(Array.from(mappings.entries())));
    renderMappings();
}

function addMapping(key, directory) {
    if (reservedMappings.includes(key)) {
        statusLine.innerHTML = `'${key}' is reserved and can not be mapped`;
        return;
    }
    let mappings = new Map(JSON.parse(localStorage.getItem('mappings')) || []);
    statusLine.innerHTML = (mappings.has(key) ? "Changed" : "Added") + ` mapping '${key}' - '${directory}'`;
    mappings.set(key, directory);
    localStorage.setItem('mappings', JSON.stringify(Array.from(mappings.entries())));
    renderMappings();
}


/*
 * Save/Load from file
 */
function saveMappings() {
    const mappings = new Map(JSON.parse(localStorage.getItem('mappings')) || []);
    let dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(Array.from(mappings)));
    let downloadElement = document.createElement('a');
    downloadElement.style = "display: none;";
    downloadElement.setAttribute("href",     dataStr);
    downloadElement.setAttribute("download", "mappings.json");
    document.body.appendChild(downloadElement); // required for firefox
    downloadElement.click();
    downloadElement.remove();
}


function loadMappings() {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';

    input.onchange = async (event) => {
        const file = event.target.files[0];
        if (!file) {
            statusLine.textContent = "No file selected";
            return;
        }
        try {
            const fileText = await file.text();
            const jsonData = JSON.parse(fileText);

            // check is valid
            if (typeof jsonData !== 'object' || jsonData === null) {
                statusLine.textContent = "Invalid JSON structure";
                return;
            }

            // TODO possibly implement sanity checks
            localStorage.setItem('mappings', JSON.stringify(jsonData));
            renderMappings();
        } catch (error) {
            console.error(error);;
            statusLine = "Error loading file";
        }
    };
    input.click();
}


// event listener for add mapping form
document.getElementById('addMappingForm').addEventListener('submit', function(event) {
    event.preventDefault();
    const key = document.getElementById('key').value;
    const directory = document.getElementById('directory').value;

    addMapping(key, directory);

    // clear input
    document.getElementById('key').value = '';
    document.getElementById('directory').value = '';
});

// load existing mappings on page load
window.onload = function() {
    renderMappings();
};

