// functionMap.js

// Create the function map
functionMap = new Map();

functionMap.set('setInnerHtml', function (socket, id, html) {
    console.log(`id = ${id}`);
    console.log(`html = ${html}`);

    const element = document.getElementById(id);
    if (element == null) {
        console.log(`No element found for id: ${id}`);
    } else {
        element.innerHTML = html;
    }
});

functionMap.set('addElementClasses', function (socket, selector, classes) {
    console.log(`selector = ${selector}`);
    console.log(`classes = ${classes}`);

    const element = document.querySelector(selector);
    if (element != null) {
        for (const clazz of classes) {
            element.classList.add(clazz);
        }
    }
});

functionMap.set('removeElementClasses', function (socket, selector, classes) {
    console.log(`selector = ${selector}`);
    console.log(`classes = ${classes}`);

    const element = document.querySelector(selector);
    if (element != null) {
        for (const clazz of classes) {
            element.classList.remove(clazz);
        }
    }
});

functionMap.set('addStyleSheet', function (socket, id, content) {
    console.log(`id = ${id}`);
    console.log(`content = ${content}`);
    addStylesheetText(id, content);
});

functionMap.set('removeStyleSheet', function (socket, id) {
    console.log(`id = ${id}`);
    removeStylesheetText(id);
});

functionMap.set('addScript', function (socket, id, content, src, onLoad) {
    console.log(`id = ${id}`);
    console.log(`content = ${content}`);
    console.log(`src = ${src}`);
    console.log(`onLoad = ${onLoad}`);

    let element = document.getElementById(id);
    if (element != null) {
        element.remove();
    }
    var script = document.createElement('script');
    script.id = id;
    if (content != null) {
        script.textContent = content;
    }
    if (src != null) {
        script.src = src;
    }
    if (onLoad != null) {
        script.addEventListener('load', (event) => {
            //window[onLoad]();
            eval(onLoad)();
        });
    }
    document.head.appendChild(script);
});

functionMap.set('removeScript', function (socket, id) {
    console.log(`id = ${id}`);
    var scriptToRemove = document.getElementById(id);
    if (scriptToRemove) {
        scriptToRemove.remove();
    } else {
        console.log('Couldn\'t found script: ${id}');
    }
});

functionMap.set('listenOnClick1', function (socket, id, widgetIds) {
    console.log(`id = ${id}`);
    console.log(`widgetIds = ${widgetIds}`);
    let element1 = document.getElementById(id);
    if (element1 == null) {
        console.log(`Element not found: ${id}`);
    } else {
        element1.onclick = async function (event) {
            event.preventDefault();
            const rootMap = new Map();
            rootMap.set('cmd', 'onClick');
            rootMap.set('id', id);
            const valueMap = new Map();
            for (const item of widgetIds) {
                const element = document.getElementById(item);
                if (element == null) {
                    console.log(`Element not found: ${item}`);
                } else if (element.tagName === 'INPUT') {
                    let value = getInputValue(element);
                    // Special processing for password input
                    if (element.type === 'password') {
                        if (window.crypto && window.crypto.subtle) {
                            const encodedValue = await getSHA384Base64(value);
                            valueMap.set(item, encodedValue);
                        }
                        else {
                            valueMap.set(item, "^"+btoa(value));
                        }
                    } else {
                        valueMap.set(item, value);
                    }
                } else if (element.tagName === 'SELECT') {
                    console.log(`selected options = ${element.selectedOptions}`);
                    const selectedOptions = Array.from(element.selectedOptions).map(option => option.value);
                    valueMap.set(item, selectedOptions);
                } else if (element.tagName === 'TEXTAREA') {
                    valueMap.set(item, element.value);
                }
            }
            rootMap.set('values', valueMap);
            const mapAsObject = mapToJson(rootMap);
            sendMessage(socket, mapAsObject);
        }
    }
});

functionMap.set('listenOnClick2', function (socket, widgetIds) {
    console.log(`widgetIds = ${widgetIds}`);

    for (const item of widgetIds) {
        let element1 = document.getElementById(item);
        if (element1 == null) {
            console.log(`Element not found: ${item}`);
        } else {
            element1.onclick = async function (event) {
                event.preventDefault();
                const rootMap = new Map();
                rootMap.set('cmd', 'onClick2');
                rootMap.set('id', item);
                const mapAsObject = mapToJson(rootMap);
                sendMessage(socket, mapAsObject);
            }
        }
    }
});

functionMap.set('openNewTab', function (socket, sameUrl, url, parameters) {
    console.log(`sameUrl = ${sameUrl}`);
    console.log(`url = ${url}`);
    console.log(`parameters = ${parameters}`);

    // Get the current URL
    var newURL;
    if (sameUrl) {
        newURL = replaceURLParams(parameters);
    } else {
        newURL = url;
    }
    console.log(`url = ${newURL}`);
    const newWindow = window.open(newURL, '_blank');
    if (newWindow) {
        // Focus the new window so that it is active
        newWindow.focus();
    } else {
        // If it was not possible to open the window, display an error message
        alert('Could not open the page in a new tab. Please check your popup settings.');
    }
});

functionMap.set('addTableRowEventListener', function (socket, id) {
    const table = document.getElementById(id);
    if (table == null) {
        console.error("addTableRowEventListener: id " + id + " not found");
    } else {
        const header = table.getElementsByTagName("th");
        const startIndex = header.length;
        const rows = table.getElementsByTagName("tr");
        for (let i = startIndex; i < rows.length; i++) {
            rows[i].addEventListener("click", function () {
                const rootMap = new Map();
                rootMap.set('cmd', 'onClickTableRow');
                rootMap.set('id', id);
                let myList = [];
                for (let c = 0; c < this.cells.length; c++) {
                    myList.push(this.cells[c].innerText);
                }
                rootMap.set('data', myList);
                const mapAsObject = mapToJson(rootMap);
                sendMessage(socket, mapAsObject);
            });
        }
    }
});

functionMap.set('addListRowEventListener', function (socket, id) {
    const list = document.getElementById(id);
    if (list == null) {
        console.error("addListRowEventListener: id " + id + " not found");
    } else {
        const rows = list.getElementsByTagName("li");
        for (let i = 0; i < rows.length; i++) {
            rows[i].addEventListener("click", function () {
                const rootMap = new Map();
                rootMap.set('cmd', 'onClickListRow');
                rootMap.set('id', id);
                let myList = [];
                for (let c = 0; c < this.cells.length; c++) {
                    myList.push(this.cells[c].innerText);
                }
                rootMap.set('data', myList);
                const mapAsObject = mapToJson(rootMap);
                sendMessage(socket, mapAsObject);
            });
        }
    }
});

functionMap.set('linkClick', function (socket, id) {
    const rootMap = new Map();
    rootMap.set('cmd', 'linkClick');
    rootMap.set('id', id);
    const mapAsObject = mapToJson(rootMap);
    sendMessage(socket, mapAsObject);
});

functionMap.set('showModal', function (socket, id) {
    const element = document.getElementById(id);
    if (element == null) {
        console.error("showModal: id not found: " + id);
    } else {
        if (UIkit) {
            UIkit.modal(element).show();
        } else {
            element.style.display = "block";
        }
    }
});

functionMap.set('showModal2', function (socket, html) {
    if (UIkit) {
        UIkit.modal.dialog(html);
    }
});

functionMap.set('setValue', function (socket, id, value) {
    replaceElementValue(id, value);
});

functionMap.set('removeElement', function (socket, id) {
    const element = document.getElementById(id);
    if (element != null) {
        element.remove();
    }
});

functionMap.set('uikitAlert', function (socket, message, options) {
    if (options === null) {
        UIkit.modal.alert(message);
    } else {
        UIkit.modal.alert(message, options);
    }
});

functionMap.set('alert', function (socket, message) {
    alert(message);
});

functionMap.set('setStylesForElements', function (socket, selector, styles) {
    const elements = document.querySelectorAll(selector);
    elements.forEach(element => {
        styles.forEach((value, property) => {
            element.style[property] = value;
        });
    });
});

functionMap.set('setImage', function (socket, id, src) {
    const element = document.getElementById(id);
    if (element != null) {
        element.src = src;
    }
});

functionMap.set('setFocus', function (socket, id) {
    const element = document.getElementById(id);
    if (element != null) {
        element.focus({ focusVisible: true });
    }
    else {
        console.log('setFocus: element ${id} not found');
    }
});
