// js/langSelector.js
/**
 * @module LanguageSelectionOverlay
 * @description Provides functionality to open a language selection overlay and inject selected translation keys into an input element.
 */

// Configuration constants
const INDEX_FILE_PATH = "../json/locale/index.json";
const LANGUAGE_DIR = "../json/locale/lang/";

// State variables
let preparedTranslations = [];
let activeInputElement = null;
let currentLanguageSelectElement = null; // Store the *currently active* select box instance for loading/updating
let externFctSetInput = null
/**
 * Debounce helper function to limit function call rate.
 * @param {Function} fn - The function to debounce.
 * @param {number} delay - The delay in milliseconds.
 * @returns {Function} - The debounced function.
 */
function debounce(fn, delay = 250) {
    let timer;
    return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => fn(...args), delay);
    };
}

/**
 * Loads the language index file and populates the given language selection dropdown.
 * @async
 * @param {HTMLSelectElement} selectElement - The <select> element to populate with language options.
 */
async function loadIndexFile(selectElement) {
    currentLanguageSelectElement = selectElement; // Keep track of the active select element

    try {
        const response = await fetch(INDEX_FILE_PATH);
        if (!response.ok) {
            throw new Error(`Failed to load index file: ${response.statusText}`);
        }
        const indexData = await response.json();

        if (selectElement) {
            selectElement.innerHTML = ''; // Clear existing options
            for (const locale in indexData.locales) {
                const option = document.createElement("option");
                option.value = locale;
                option.textContent = indexData.locales[locale].label;
                selectElement.appendChild(option);
            }

            selectElement.value = indexData.default; // Set default language
            loadLanguageFile(selectElement.value); // Load initial language data for the overlay
        } else {
            console.warn("Language select element not provided to loadIndexFile. Cannot populate language options.");
        }
    } catch (error) {
        console.error("Error loading language index file:", error);
    }
}

/**
 * Loads a specific language file based on the locale.
 * @async
 * @param {string} locale - The locale identifier (e.g., 'en', 'de').
 */
async function loadLanguageFile(locale) {
    try {
        const response = await fetch(`${LANGUAGE_DIR}${locale}.json`);
        if (!response.ok) {
            throw new Error(`Failed to load language file for ${locale}: ${response.statusText}`);
        }
        const translations = await response.json();
        prepareTranslations(translations);
        // Only render the translation list if the overlay is actually visible
        if (document.getElementById("lang-overlay") && !document.getElementById("lang-overlay").classList.contains("hidden")) {
            renderTranslationList();
        }
    } catch (error) {
        console.error(`Error loading language file for ${locale}:`, error);
    }
}

/**
 * Prepares the raw translations into a format suitable for filtering and rendering.
 * @param {object} translations - The raw translation object.
 */
function prepareTranslations(translations) {
    preparedTranslations = Object.entries(translations).map(
        ([key, value]) => ({
            key,
            value: String(value),
            keyLower: key.toLowerCase(),
            valueLower: String(value).toLowerCase()
        })
    );
}

/**
 * Renders or re-renders the list of translations within the overlay.
 * Filters are applied based on the current input values.
 */
function renderTranslationList() {
    const translationList = document.getElementById("translation-list");
    if (!translationList) return; // Overlay might not be created yet

    const filterKeyInput = document.getElementById("filter-key");
    const filterValueInput = document.getElementById("filter-value");

    const keyFilter = filterKeyInput ? filterKeyInput.value.toLowerCase() : '';
    const valueFilter = filterValueInput ? filterValueInput.value.toLowerCase() : '';

    function includeWords(sText, arW) {
        // sText = sText.toLowerCase()
        for (let i = 0; i < arW.length; i++)
            if (!sText.includes(arW[i])) return false
        return true
    }
    // Clear previous entries, keeping the header
    translationList.querySelectorAll(".row:not(.header)").forEach(row => row.remove());
    let arKF = keyFilter.split(" ")
    let arVF = valueFilter.split(" ")
    for (const item of preparedTranslations) {
        if ((!keyFilter || includeWords(item.keyLower, arKF)) &&
            (!valueFilter || includeWords(item.valueLower, arVF))) {
            // if ((!keyFilter || item.keyLower.includes(keyFilter)) &&
            //     (!valueFilter || item.valueLower.includes(valueFilter))) {
            const row = document.createElement("div");
            row.className = "grid row";

            row.innerHTML = `
                <div class="cell">${item.key}</div>
                <div class="cell">${item.value}</div>
            `;

            row.addEventListener("click", () => {
                if (activeInputElement) {
                    activeInputElement.value += "${" + item.key + "}"; // append selected key
                    let e = {}
                    e.target = activeInputElement
                    externFctSetInput(e)
                }
                document.getElementById("lang-overlay").classList.add("hidden");
            });

            translationList.appendChild(row);
        }
    }
}

const debouncedRender = debounce(renderTranslationList);

/**
 * Creates and appends the language selection overlay HTML to the body.
 * NOTE: The CSS for this overlay is expected to be present in the main HTML file's <head>.
 */
function createOverlayHtml() {
    const overlayHtml = `
        <div id="lang-overlay" class="overlay hidden">
            <div class="overlay-content">
                <div class="overlay-header">
                    <h4>Select language variable</h4>
                    <button id="close-overlay">✕</button>
                </div>

                <!-- Filters -->
                <div class="grid filter-row">
                    <input id="filter-key" placeholder="Filter key">
                    <input id="filter-value" placeholder="Filter value">
                </div>

                <!-- Table -->
                <div id="translation-list">
                    <div class="grid row header">
                        <div class="cell">Key</div>
                        <div class="cell">Value</div>
                    </div>
                </div>
            </div>
        </div>
    `;
    document.body.insertAdjacentHTML('beforeend', overlayHtml);
}

/**
 * Initializes the event listeners for the overlay (filters, close button).
 * This function does NOT handle loading the language index file,
 * as that depends on the `createLanguageSelectBox` being called and the element being in the DOM.
 */
function initializeOverlayListeners() {
    const overlay = document.getElementById("lang-overlay");
    const closeOverlayButton = document.getElementById("close-overlay");
    const filterKeyInput = document.getElementById("filter-key");
    const filterValueInput = document.getElementById("filter-value");

    if (closeOverlayButton) {
        closeOverlayButton.addEventListener("click", () => {
            overlay.classList.add("hidden");
        });
    }

    if (filterKeyInput) {
        filterKeyInput.addEventListener("input", debouncedRender);
    }
    if (filterValueInput) {
        filterValueInput.addEventListener("input", debouncedRender);
    }
}


/**
 * Opens the language selection overlay.
 * @param {HTMLInputElement} inputElement - The input element to which the selected translation key should be written.
 */
export function openLanguageSelectionOverlay(inputElement, fctSetInput) {
    externFctSetInput = fctSetInput
    activeInputElement = inputElement;

    const overlay = document.getElementById("lang-overlay");
    const filterKeyInput = document.getElementById("filter-key");

    if (!overlay) {
        console.error("Language overlay not found. It should be created on DOMContentLoaded.");
        return;
    }

    // Reset filters
    if (filterKeyInput) filterKeyInput.value = "";
    const filterValueInput = document.getElementById("filter-value");
    if (filterValueInput) filterValueInput.value = "";

    renderTranslationList();
    overlay.classList.remove("hidden");
    if (filterKeyInput) filterKeyInput.focus();
}

/**
 * Creates and returns the HTML for the language selection dropdown.
 * Call this function from your main HTML to place the dropdown.
 *
 * @param {boolean} [loadInitialData=true] - If true, this will also trigger loading of the index file
 *                                          and populate the select box with language options.
 * @returns {HTMLSelectElement} - The created select element.
 */
export function createLanguageSelectBox(loadInitialData = true) {
    const selectBox = document.createElement("select");
    selectBox.id = "language-select";
    selectBox.addEventListener("change", (e) => {
        loadLanguageFile(e.target.value);
    });

    // Store a reference to this selectBox if it's the main one being used.
    currentLanguageSelectElement = selectBox;

    if (loadInitialData) {
        // Trigger loading the index file and populating the select box
        loadIndexFile(selectBox);
    }
    return selectBox;
}


// Initial setup: Create overlay HTML once the module is loaded (but hidden)
// It will only become visible when openLanguageSelectionOverlay is called.
document.addEventListener('DOMContentLoaded', () => {
    // Only create overlay HTML if it doesn't already exist.
    // This prevents issues if the script runs multiple times or is included incorrectly.
    if (!document.getElementById("lang-overlay")) {
        createOverlayHtml();
    }
    initializeOverlayListeners(); // Initialize listeners for the overlay (filters, close button)
});