import * as FilterDataModule from "../data/filter-data.js";

import { MARKET_DATA } from "../data/market-data.js";

class FilterUtils {
    static normalizeValue(val) {
        if (val === null || val === undefined || val === "") return null;
        const parsed = parseFloat(val);
        return isNaN(parsed) ? null : parsed;
    }
    static debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }
    static deepClone(obj) {
        try {
            return JSON.parse(JSON.stringify(obj));
        } catch (e) {
            return obj;
        }
    }
    static getNestedValue(obj, path) {
        return path.split(".").reduce((acc, part) => acc?.[part], obj);
    }
}

export class DynamicFilterManager {
    constructor(screenerInstance) {
        this.screener = screenerInstance;
        this.rootNode = screenerInstance.rootNode || document;
        this.marketData = typeof MARKET_DATA !== "undefined" ? MARKET_DATA : {};
        this.iconPath = typeof ICON_PATH !== "undefined" ? ICON_PATH : "";
        this.iconType = typeof ICON_TYPE !== "undefined" ? ICON_TYPE : ".svg";
        this.assetType = screenerInstance.CONFIG?.CURRENT_ASSET_TYPE || (typeof asset_type !== "undefined" ? asset_type : "crypto");
        this.CONFIG = {
            SEARCH_THRESHOLD: 7,
            MAX_HEIGHT: {
                DEFAULT: 100,
                SELECT_FILTER: 70,
                COUNTRY_FILTER: 50
            },
            DEBOUNCE_DELAY: 300,
            ANIMATION_DURATION: 200,
            DEFAULT_FILTERS: FilterDataModule.getDefaultFilters(this.assetType)
        };
        this.CONDITIONS = FilterDataModule.getFilterConditions();
        this.state = {
            activeFilters: {},
            availableMetrics: [],
            category: this.assetType,
            storageKey: `filters_${this.assetType}`,
            isPrimary: true,
            primaryStorageKey: `is_primary_${this.assetType}`,
            apiOptionsCache: {},
            apiOptionsLoading: {}
        };
        this.dom = {};
        this.eventCleanupTasks = [];
        this.init();
    }
    init() {
        try {
            this.#cacheDOMElements();
            this.#loadFilterableMetrics();
            this.#loadPrimaryToggleState();
            this.#setupGlobalEventListeners();
            this.#loadFiltersOnPageLoad();
        } catch (error) {
            console.error("Filter Manager init error:", error);
            this.#showError("Failed to initialize filters. Please refresh the page.");
        }
    }
    #cacheDOMElements() {
        this.dom = {
            addFilterBtn: this.rootNode.querySelector("#addFilterBtn"),
            filterContainer: this.rootNode.querySelector(".filters-container"),
            filterPanel: this.rootNode.querySelector(".filter-panel"),
            applyFiltersBtn: this.rootNode.querySelector(".apply-filters-btn"),
            resetFiltersBtn: this.rootNode.querySelector(".reset-filters-btn"),
            filterToggle: this.rootNode.querySelector(".filter-toggle-btn"),
            filterPresetSelect: this.rootNode.querySelector("#filterPresetSelect"),
            filterSelectorList: this.rootNode.querySelector(".filter-selector-list"),
            fixFilterContainer: this.rootNode.querySelector(".fix-filter-not-clean")
        };
    }
    #loadPrimaryToggleState() {
        const configDefault = this.screener?.CONFIG?.DEFAULT_IS_PRIMARY;
        const defaultValue = configDefault !== false && configDefault !== 0;
        try {
            if (this.screener?.CONFIG?.ENABLE_STORAGE === false) {
                this.state.isPrimary = defaultValue;
                return;
            }
            const stored = STORAGE.get(this.state.primaryStorageKey);
            this.state.isPrimary = stored !== null ? stored === true || stored === "true" : defaultValue;
        } catch (e) {
            this.state.isPrimary = defaultValue;
        }
    }
    #savePrimaryToggleState() {
        if (this.screener?.CONFIG?.ENABLE_STORAGE === false) return;
        try {
            STORAGE.set(this.state.primaryStorageKey, this.state.isPrimary);
        } catch (e) {}
    }
    #loadFilterableMetrics() {
        try {
            let metrics = this.screener.getMetrics("filter");
            if (typeof metrics === "string") {
                metrics = JSON.parse(metrics);
            }
            this.state.availableMetrics = this.#normalizeMetrics(metrics);
        } catch (error) {
            this.state.availableMetrics = [];
        }
    }
    #normalizeMetrics(metrics) {
        if (Array.isArray(metrics)) return metrics;
        if (typeof metrics === "object" && metrics !== null) {
            return Object.values(metrics);
        }
        return [];
    }
    #showError(message) {}
    #loadFiltersOnPageLoad() {
        const storedFilters = this.#getStoredFilters();
        if (storedFilters && Object.keys(storedFilters).length > 0) {
            this.#loadStoredFilters(storedFilters);
        } else {
            this.#loadDefaultFilters();
            const embedFilters = this.screener?.CONFIG?.EMBED_DEFAULT_FILTERS;
            if (embedFilters && typeof embedFilters === "object" && Object.keys(embedFilters).length > 0) {
                this.#applyEmbedDefaultFilters(embedFilters);
            }
        }
    }
    #getStoredFilters() {
        if (this.screener?.CONFIG?.ENABLE_STORAGE === false) return null;
        try {
            const stored = STORAGE.get(this.state.storageKey);
            return stored || null;
        } catch (e) {
            return null;
        }
    }
    #loadStoredFilters(filters) {
        this.state.activeFilters = FilterUtils.deepClone(filters);
        const fragment = document.createDocumentFragment();
        const metricsToRender = [];
        Object.entries(filters).forEach(([metricKey, filterValue]) => {
            const metric = this.#getMetricByKey(metricKey);
            if (metric) {
                metricsToRender.push({
                    metric: metric,
                    filterValue: filterValue
                });
            }
        });
        metricsToRender.forEach(({metric: metric, filterValue: filterValue}) => {
            this.#renderFilterDropdown(metric, filterValue);
        });
        requestAnimationFrame(() => {
            metricsToRender.forEach(({metric: metric, filterValue: filterValue}) => {
                if (metric.filter_type === "select" && filterValue?.value) {
                    const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${metric.key}"]`);
                    const dropdown = filterItem?.querySelector(".dropdown-select");
                    const customSelectAPI = dropdown?.customSelectAPI;
                    if (customSelectAPI && typeof customSelectAPI.setValue === "function") {
                        customSelectAPI.setValue(filterValue.value);
                    }
                    if (metric.data_multiple === true && metric.max_selected) {
                        this.#updateMaxSelectedState(metric.key, filterValue.value);
                    }
                }
                this.#updateFilterLabel(metric.key);
                this.#updateResetButtonVisibility(metric.key);
                this.#updateFilterActiveClass(metric.key);
            });
        });
        this.#setFiltersToScreenerState();
    }
    #applyEmbedDefaultFilters(embedFilters) {
        const operatorToCondition = {};
        Object.entries(this.CONDITIONS).forEach(([condKey, cond]) => {
            operatorToCondition[cond.operator] = condKey;
        });
        const pathToMetric = {};
        this.state.availableMetrics.forEach(m => {
            if (m?.path) pathToMetric[m.path] = m;
        });
        const appliedMetrics = [];
        Object.entries(embedFilters).forEach(([apiKey, value]) => {
            const operatorMatch = apiKey.match(/(_gt|_gte|_lt|_lte|_eq|_between)$/);
            if (!operatorMatch) return;
            const operator = operatorMatch[1];
            const path = apiKey.substring(0, apiKey.length - operator.length);
            const conditionKey = operatorToCondition[operator];
            const metric = pathToMetric[path];
            if (!metric || !conditionKey) return;
            const condConfig = this.CONDITIONS[conditionKey];
            if (!condConfig) return;
            const filterData = {
                condition: conditionKey,
                min: null,
                max: null,
                value: null
            };
            if (condConfig.api_format === "range") {
                const parts = String(value).split(",");
                filterData.min = parts[0] ? Number(parts[0]) : null;
                filterData.max = parts[1] ? Number(parts[1]) : null;
            } else if (metric.filter_type === "select") {
                filterData.value = value;
            } else {
                const inputType = condConfig.inputs || "min";
                filterData[inputType] = Number(value);
            }
            const existingItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${metric.key}"]`);
            if (!existingItem) {
                this.#renderFilterDropdown(metric, filterData);
            }
            this.state.activeFilters[metric.key] = filterData;
            appliedMetrics.push(metric.key);
        });
        if (appliedMetrics.length > 0) {
            requestAnimationFrame(() => {
                requestAnimationFrame(() => {
                    appliedMetrics.forEach(metricKey => {
                        this.#updateFilterLabel(metricKey);
                        this.#updateFilterActiveClass(metricKey);
                    });
                });
            });
            this.#setFiltersToScreenerState();
        }
    }
    #loadDefaultFilters() {
        this.CONFIG.DEFAULT_FILTERS.forEach(metricKey => {
            const metric = this.#getMetricByKey(metricKey);
            if (metric) {
                const defaultValue = {
                    condition: "between",
                    min: null,
                    max: null,
                    value: null
                };
                this.state.activeFilters[metricKey] = defaultValue;
                this.#renderFilterDropdown(metric, defaultValue);
            }
        });
    }
    #getMetricByKey(key) {
        if (!key || !this.state.availableMetrics) return null;
        const metric = this.state.availableMetrics.find(m => m?.key === key);
        if (!metric) {}
        return metric || null;
    }
    #renderFilterDropdown(metric, filterData) {
        if (!metric?.key) {
            return;
        }
        if (metric.key === "country") {
            this.#renderCountryFilter(metric, filterData);
            return;
        }
        const isSelectFilter = metric.filter_type === "select";
        const isRangeFilter = !isSelectFilter;
        const allowedConditions = this.#getAvailableConditions(metric);
        const showManualBtn = isRangeFilter && allowedConditions !== false;
        const predefinedValues = isRangeFilter ? FilterDataModule.getPredefinedValue(metric.key, this.state.category) : null;
        const hasPredefinedValues = predefinedValues && predefinedValues.length > 0;
        let selectOptionsHTML = "";
        let optionsCount = 0;
        let maxHeightOffset = this.CONFIG.MAX_HEIGHT.DEFAULT;
        if (isSelectFilter) {
            maxHeightOffset = this.CONFIG.MAX_HEIGHT.SELECT_FILTER;
            const result = this.#generateSelectOptions(metric, filterData);
            selectOptionsHTML = result.html;
            optionsCount = result.count;
        } else if (hasPredefinedValues) {
            selectOptionsHTML = this.#generatePredefinedOptions(predefinedValues, filterData);
            optionsCount = predefinedValues.length;
        }
        const enableSearch = isSelectFilter && (optionsCount > this.CONFIG.SEARCH_THRESHOLD || metric.searchable === true);
        const searchAttr = enableSearch ? 'data-search="true"' : "";
        const isMultiple = metric.data_multiple === true;
        const multipleAttr = isMultiple ? 'data-multiple="true"' : "";
        const manualHTML = isRangeFilter ? this.#generateManualFilterUI(metric, allowedConditions, filterData) : "";
        const selectedLabel = this.#getSelectedLabel(metric, filterData, predefinedValues);
        const dropdownHTML = `\n            <div class="filter-item" data-filter-key="${metric.key}" data-has-predefined="${hasPredefinedValues}">\n                <div class="dropdown-select no-auto-highlight" ${searchAttr} ${multipleAttr}>\n                    <div class="select-trigger">\n                        <span class="select-trigger-text-nochange">${selectedLabel}</span>\n                        <svg width="18" height="18" class="select-arrow" fill="none" stroke="currentColor">\n                            <use href="#chevron-down"></use>\n                        </svg>\n                    </div>\n                    \n                    <div class="select-dropdown">    \n                        <div class="select-header" style="display: none;">\n                            <div class="back-to-main-btn"><svg width="22" height="22" fill="none" stroke="currentColor"><use href="#chevron-left"></use></svg>${getLang("filters.ui.manual_setup", "Manual setup")}</div>\n                        </div>\n                        \n                        \x3c!-- Main View --\x3e\n                        <div class="select-body select-body-main" style="${!hasPredefinedValues && isRangeFilter ? "display: none;" : ""}">\n                            <ul class="select-options" data-max-height-offset="${maxHeightOffset}">\n                                ${selectOptionsHTML}\n                            </ul>\n                        </div>\n                        \n                        \x3c!-- Manual View --\x3e\n                        <div class="select-body select-body-manual" style="${hasPredefinedValues || !isRangeFilter ? "display: none;" : ""}">\n                            ${manualHTML}\n                        </div>\n                        \n                        <div class="select-footer">\n                            ${showManualBtn && hasPredefinedValues ? `<div class="manual-filter-btn"><svg width="18" height="18" fill="none" stroke="currentColor"><use href="#setup"></use></svg>${getLang("filters.ui.manual_setup", "Manual setup")}</div>` : ""}\n                            <div class="apply-manual-btn" style="${!hasPredefinedValues && isRangeFilter ? "" : "display: none;"}"><svg width="18" height="18" fill="none" stroke="currentColor"><use href="#apply"></use></svg>${getLang("filters.ui.apply", "Apply")}</div>\n                            <div class="reset-filter-btn-footer" style="display: none;"><svg width="18" height="18" fill="none" stroke="currentColor"><use href="#reset"></use></svg>${getLang("filters.ui.reset", "Reset")}</div>\n                            <div class="remove-filter-btn"><svg width="18" height="18" fill="none" stroke="currentColor"><use href="#remove"></use></svg>${getLang("filters.ui.remove", "Remove")}</div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        `;
        const addFilterWrapper = this.rootNode.querySelector(".add-filter-wrapper");
        if (addFilterWrapper) {
            addFilterWrapper.insertAdjacentHTML("beforebegin", dropdownHTML);
        }
        this.#attachFilterItemEvents(metric.key);
        requestAnimationFrame(() => {
            if (typeof initCustomSelects === "function") {
                initCustomSelects(".filter-panel", this.rootNode);
            }
            if (hasPredefinedValues || isSelectFilter) {
                this.#attachSelectOptionEvents(metric.key);
            }
            if (!hasPredefinedValues && isRangeFilter) {
                this.#attachManualInputEvents(metric.key, allowedConditions);
            }
        });
    }
    #generateSelectOptions(metric, filterData) {
        const loadOptions = metric.load_options;
        const noOptionsText = getLang("filters.ui.no_options", "No options available");
        const noExchangesText = getLang("filters.ui.no_exchanges", "No exchanges available");
        const invalidOptionsText = getLang("filters.ui.invalid_options", "Invalid options format");
        const clickToLoadText = getLang("filters.ui.click_to_load", "Click to load options");
        if (metric.load_options_api) {
            if (this.state.apiOptionsCache[metric.key]) {
                const cachedOptions = this.state.apiOptionsCache[metric.key];
                return this.#generateApiOptionsHTML(metric.key, cachedOptions, filterData);
            }
            return {
                html: `<li class="select-option disabled api-load-placeholder">${clickToLoadText}</li>`,
                count: 0
            };
        }
        if (!loadOptions) {
            return {
                html: `<li class="select-option">${noOptionsText}</li>`,
                count: 0
            };
        }
        let options;
        options = typeof loadOptions === "string" ? FilterUtils.getNestedValue(this.marketData, `${this.state.category}.${loadOptions}`) : loadOptions;
        if (!options) {
            if (metric.key === "exchange") {
                options = this.#getExchangesForSelectedCountry();
                if (!options) {
                    return {
                        html: `<li class="select-option">${noExchangesText}</li>`,
                        count: 0
                    };
                }
            } else {
                return {
                    html: `<li class="select-option">${noOptionsText}</li>`,
                    count: 0
                };
            }
        }
        const isExchangeFilter = metric.key === "exchange";
        const isNetworkFilter = metric.key === "blockchain-network";
        const isMultiple = metric.data_multiple === true;
        if (typeof options !== "object") {
            return {
                html: `<li class="select-option">${invalidOptionsText}</li>`,
                count: 0
            };
        }
        const optionsArray = Object.entries(options);
        const optionsCount = optionsArray.length;
        let selectedValues = [];
        if (isMultiple && filterData?.value) {
            selectedValues = Array.isArray(filterData.value) ? filterData.value : filterData.value.split(",");
        }
        const optionsHTML = optionsArray.map(([key, value]) => {
            let isSelected = false;
            const optionValue = value?.value || key;
            let optionLabel;
            if (typeof value === "string") {
                optionLabel = value;
            } else if (typeof value === "object" && value !== null) {
                optionLabel = value.label || key;
            } else {
                const translated = getLang(`select_options.${metric.key}.${key}`);
                optionLabel = translated !== key.toLowerCase() ? translated : key;
            }
            const optionIcon = value?.icon || key;
            if (isMultiple) {
                isSelected = selectedValues.includes(optionValue);
            } else {
                isSelected = filterData?.value === optionValue;
            }
            if (isExchangeFilter || isNetworkFilter) {
                return `\n                    <li class="select-option ${isSelected ? "selected" : ""}" data-value="${optionValue}">\n                        <span class="select-option-img">\n                            <div class="flag-icon-container">\n                                <img data-src="${this.iconPath}${isExchangeFilter ? "exchange" : "blockchain"}/${optionIcon}${this.iconType}" alt="${optionLabel}" class="flag-img">\n                            </div> \n                            ${optionLabel}\n                        </span>\n                    </li>\n                `;
            }
            return `\n                <li class="select-option ${isSelected ? "selected" : ""}" data-value="${optionValue}">\n                    ${optionLabel}\n                </li>\n            `;
        }).join("");
        return {
            html: optionsHTML,
            count: optionsCount
        };
    }
    #getExchangesForSelectedCountry() {
        const availableExchangesString = this.screener?.state?.cachedApiData?.info?.available_exchanges;
        if (!availableExchangesString) {
            return null;
        }
        const availableExchanges = availableExchangesString.split(",").map(ex => ex.trim()).filter(ex => ex.length > 0);
        if (availableExchanges.length === 0) {
            return null;
        }
        const exchangesObject = {};
        availableExchanges.forEach(exchangeName => {
            const exchangeKey = exchangeName.toLowerCase();
            exchangesObject[exchangeKey] = {
                label: exchangeName,
                value: exchangeKey,
                icon: exchangeKey
            };
        });
        return exchangesObject;
    }
    #updateExchangeOnDataChange() {
        const exchangeFilter = this.rootNode.querySelector('.filter-item[data-filter-key="exchange"]');
        if (!exchangeFilter) {
            return;
        }
        const newExchanges = this.#getExchangesForSelectedCountry();
        if (!newExchanges || Object.keys(newExchanges).length === 0) {
            return;
        }
        const currentExchangeValue = this.state.activeFilters["exchange"]?.value;
        const metric = this.#getMetricByKey("exchange");
        if (!metric) return;
        const filterData = this.state.activeFilters["exchange"] || {
            value: null
        };
        const optionsHTML = this.#generateExchangeOptionsHTML(newExchanges, filterData);
        const dropdown = exchangeFilter.querySelector(".dropdown-select");
        const customSelectAPI = dropdown?.customSelectAPI;
        const selectOptions = exchangeFilter.querySelector(".select-options");
        if (selectOptions) {
            selectOptions.innerHTML = optionsHTML;
        }
        this.#updateFilterLabel("exchange");
        this.#updateResetButtonVisibility("exchange");
        this.#updateFilterActiveClass("exchange");
        requestAnimationFrame(() => {
            this.#attachSelectOptionEvents("exchange");
        });
    }
    #resetExchangeFilter() {
        const exchangeFilter = this.rootNode.querySelector('.filter-item[data-filter-key="exchange"]');
        if (!exchangeFilter) {
            return;
        }
        if (this.state.activeFilters["exchange"]) {
            this.state.activeFilters["exchange"].value = null;
        }
        const dropdown = exchangeFilter.querySelector(".dropdown-select");
        const customSelectAPI = dropdown?.customSelectAPI;
        if (customSelectAPI && typeof customSelectAPI.setValue === "function") {
            customSelectAPI.setValue(null);
        }
        this.#updateFilterLabel("exchange");
        this.#updateResetButtonVisibility("exchange");
        this.#updateFilterActiveClass("exchange");
        this.#saveFiltersToStorage();
    }
    #generateExchangeOptionsHTML(exchanges, filterData) {
        const metric = this.#getMetricByKey("exchange");
        const isMultiple = metric?.data_multiple === true;
        let selectedValues = [];
        if (isMultiple && filterData?.value) {
            selectedValues = Array.isArray(filterData.value) ? filterData.value : filterData.value.split(",");
        }
        return Object.entries(exchanges).map(([key, value]) => {
            let isSelected = false;
            const optionValue = value?.value || key;
            const optionLabel = value?.label || value;
            const optionIcon = value?.icon || key;
            if (isMultiple) {
                isSelected = selectedValues.includes(optionValue);
            } else {
                isSelected = filterData?.value === optionValue;
            }
            return `\n                <li class="select-option ${isSelected ? "selected" : ""}" data-value="${optionValue}">\n                    <span class="select-option-img">\n                        <div class="flag-icon-container">\n                            <img data-src="${this.iconPath}exchange/${optionIcon}${this.iconType}" alt="${optionLabel}" class="flag-img">\n                        </div> \n                        ${optionLabel}\n                    </span>\n                </li>\n            `;
        }).join("");
    }
    #updateCurrencyInManualFilters(countryValue) {
        const COUNTRIES = FilterUtils.getNestedValue(this.marketData, "stock.country") || {};
        const countryMetric = this.#getMetricByKey("country");
        const isCountryMultiple = countryMetric?.data_multiple === true;
        let newCurrency = "";
        if (isCountryMultiple) {
            const selectedCountries = Array.isArray(countryValue) ? countryValue : countryValue ? countryValue.split(",") : [];
            if (selectedCountries.length > 0) {
                const firstCountryData = COUNTRIES[selectedCountries[0]];
                if (firstCountryData && firstCountryData.currency) {
                    newCurrency = firstCountryData.currency;
                }
            }
        } else {
            const countryData = COUNTRIES[countryValue];
            if (countryData && countryData.currency) {
                newCurrency = countryData.currency;
            }
        }
        if (!newCurrency) {
            return;
        }
        const filterPanel = this.rootNode.querySelector(".filter-panel");
        if (!filterPanel) return;
        filterPanel.querySelectorAll(".filter-item").forEach(filterItem => {
            const filterKey = filterItem.dataset.filterKey;
            if (filterKey === "country") return;
            const metric = this.#getMetricByKey(filterKey);
            if (!metric) return;
            if (metric.currency !== "USD") return;
            filterItem.querySelectorAll(".select-body-manual .input-prefix").forEach(prefixEl => {
                const currentValue = prefixEl.textContent.trim();
                if (currentValue === "USD" || currentValue.length === 3) {
                    prefixEl.textContent = newCurrency;
                }
                if (this.state.category === "forex") {
                    if (currentValue === "USD") {
                        prefixEl.textContent = "";
                        prefixEl.style.display = "none";
                    }
                }
            });
        });
    }
    #renderCountryFilter(metric, filterData) {
        const defaultCountry = this.screener?.CONFIG?.DEFAULT_COUNTRY || "all";
        const isMultiple = metric?.data_multiple === true;
        const multipleAttr = isMultiple ? 'data-multiple="true"' : "";
        let selectedValues = [];
        let selectedCountry = defaultCountry;
        if (isMultiple) {
            if (filterData?.value) {
                selectedValues = Array.isArray(filterData.value) ? filterData.value : filterData.value.split(",");
            } else {
                selectedValues = [ defaultCountry ];
                this.state.activeFilters["country"] = {
                    value: selectedValues
                };
            }
        } else {
            selectedCountry = filterData?.value || defaultCountry;
            if (!filterData?.value) {
                this.state.activeFilters["country"] = {
                    value: selectedCountry
                };
            }
        }
        const countryOptions = FilterUtils.getNestedValue(this.marketData, "stock.country") || {};
        let countryOptionsHTML = "";
        for (const [code, name] of Object.entries(countryOptions)) {
            let isSelected = false;
            if (isMultiple) {
                isSelected = selectedValues.includes(code);
            } else {
                isSelected = selectedCountry === code;
            }
            countryOptionsHTML += `\n                <li class="select-option ${isSelected ? "selected" : ""}" data-value="${code}">\n                    <span class="select-option-img">\n                        <div class="flag-icon-container">\n                            <img data-src="${this.iconPath}country/${code}${this.iconType}" alt="${name.name}" class="flag-img">\n                        </div> \n                        ${name.name}\n                    </span>\n                </li>\n            `;
        }
        let selectedCountryDisplay = "";
        let iconHTML = "";
        if (isMultiple) {
            if (selectedValues.length === 0) {
                selectedCountryDisplay = "Country";
                iconHTML = "";
            } else if (selectedValues.length === 1) {
                const code = selectedValues[0];
                const countryData = countryOptions[code];
                selectedCountryDisplay = countryData ? countryData["name"] : code;
                iconHTML = `<img data-src="${this.iconPath}country/${code}${this.iconType}" alt="${code}" class="flag-img">`;
            } else {
                selectedCountryDisplay = `Country <span class="select-trigger-text-count">${selectedValues.length}</span>`;
                iconHTML = `<svg width="100%" height="100%" fill="none" stroke="currentColor">\n                    <use href="#global"></use>\n                </svg>`;
            }
        } else {
            const countryData = countryOptions[selectedCountry];
            selectedCountryDisplay = countryData ? countryData["name"] : selectedCountry;
            iconHTML = `<img data-src="${this.iconPath}country/${selectedCountry}${this.iconType}" alt="${selectedCountry}" class="flag-img">`;
        }
        const primaryIconDisplay = this.state.isPrimary ? "" : 'style="display: none;"';
        const primaryChecked = this.state.isPrimary ? "checked" : "";
        const countryHTML = `\n            <div class="filter-item" data-filter-key="country">\n                <div class="dropdown-select no-auto-highlight" data-search="true" ${multipleAttr}>\n                    <div class="select-trigger">\n                        <span class="select-trigger-text-nochange">\n                            <div class="flag-icon-container">\n                                ${iconHTML}\n                            </div> \n                            ${selectedCountryDisplay}\n                        </span>\n                        <svg class="ms-2 country-text-primary-icon" width="18" height="18" fill="none" stroke="currentColor" ${primaryIconDisplay}><use href="#primary"></use></svg>\n                        <svg width="18" height="18" class="select-arrow" fill="none" stroke="currentColor">\n                            <use href="#chevron-down"></use>\n                        </svg>\n                    </div>\n                    \n                    <div class="select-dropdown">\n                        <ul class="select-options" data-max-height-offset="${this.CONFIG.MAX_HEIGHT.COUNTRY_FILTER}">\n                            ${countryOptionsHTML}\n                        </ul>\n                        <div class="select-footer">\n                            <div>\n                                <div class="select-footer-inner"><svg width="20" height="20" fill="none" stroke="currentColor"><use href="#primary"></use></svg>${getLang("menu_search.actions.primary_listing", "Primary listing")}</div>\n                                <div class="primary-toggle">\n                                    <input type="checkbox" id="primaryToggle" class="primary-checkbox" ${primaryChecked}>\n                                    <label for="primaryToggle" class="primary-label">\n                                        <div class="toggle-ball"></div>\n                                    </label>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        `;
        if (this.dom.fixFilterContainer) {
            this.dom.fixFilterContainer.insertAdjacentHTML("beforeend", countryHTML);
        }
        this.#attachFilterItemEvents("country");
        this.#attachSelectOptionEvents("country");
        this.#attachPrimaryToggleEvents();
        this.#updatePrimaryIconVisibility();
        requestAnimationFrame(() => {
            if (typeof initCustomSelects === "function") {
                initCustomSelects(".fix-filter-not-clean", this.rootNode);
            }
        });
    }
    #generatePredefinedOptions(predefinedValues, filterData) {
        if (!predefinedValues) return "";
        return predefinedValues.map(option => {
            const optionCondition = option.condition || "between";
            const isSelected = filterData && filterData.min == option.min && filterData.max == option.max && filterData.condition === optionCondition;
            const minAttr = option.min != null ? `data-min="${option.min}"` : "";
            const maxAttr = option.max != null ? `data-max="${option.max}"` : "";
            return `\n                <li class="select-option ${isSelected ? "selected" : ""}" ${minAttr} ${maxAttr} data-condition="${optionCondition}">\n                    ${option.label}\n                </li>\n            `;
        }).join("");
    }
    #getSelectedLabel(metric, filterData, predefinedValues) {
        const metricLabel = metric.label;
        if (!filterData) return metricLabel;
        if (metric.filter_type === "select") {
            if (filterData.value) {
                if (metric.data_multiple === true) {
                    const values = Array.isArray(filterData.value) ? filterData.value : filterData.value.split(",");
                    if (values.length === 1) {
                        const selectedOption = this.rootNode.querySelector(`.filter-item[data-filter-key="${metric.key}"] .select-option[data-value="${values[0]}"]`);
                        if (selectedOption) {
                            const optionHTML = selectedOption.innerHTML;
                            return `${metricLabel}: ${optionHTML}`;
                        }
                        const translatedValue = getLang(`select_options.${metric.key}.${values[0]}`, values[0]);
                        return `${metricLabel}: ${translatedValue}`;
                    } else if (values.length > 1) {
                        return `${metricLabel} <span class="select-trigger-text-count">${values.length}</span>`;
                    }
                } else {
                    const selectedOption = this.rootNode.querySelector(`.filter-item[data-filter-key="${metric.key}"] .select-option[data-value="${filterData.value}"]`);
                    if (selectedOption) {
                        const optionHTML = selectedOption.innerHTML;
                        return `${metricLabel}: ${optionHTML}`;
                    }
                    const translatedValue = getLang(`select_options.${metric.key}.${filterData.value}`, filterData.value);
                    return `${metricLabel}: ${translatedValue}`;
                }
            }
            return metricLabel;
        }
        if (filterData.value != null && filterData.condition === "equal") {
            const conditionConfig = this.CONDITIONS["equal"];
            if (conditionConfig) {
                const svgId = conditionConfig.svg_id;
                const iconHTML = `<svg width="18" height="18" fill="none" stroke="currentColor"><use href="#${svgId}"></use></svg>`;
                return `${metricLabel}: ${iconHTML} ${filterData.value}`;
            }
        }
        if (!filterData.min && !filterData.max && !filterData.value) return metricLabel;
        if (predefinedValues?.length > 0) {
            const filterMin = FilterUtils.normalizeValue(filterData.min);
            const filterMax = FilterUtils.normalizeValue(filterData.max);
            const match = predefinedValues.find(opt => {
                const optMin = FilterUtils.normalizeValue(opt.min);
                const optMax = FilterUtils.normalizeValue(opt.max);
                return optMin === filterMin && optMax === filterMax;
            });
            if (match) {
                const condition = match.condition || filterData.condition || "between";
                const conditionConfig = this.CONDITIONS[condition];
                if (conditionConfig) {
                    const svgId = conditionConfig.svg_id;
                    const iconHTML = `<svg width="18" height="18" fill="none" stroke="currentColor"><use href="#${svgId}"></use></svg>`;
                    if (filterData.min != null && filterData.max != null) {
                        return `${metricLabel}: ${iconHTML} ${filterData.min} to ${filterData.max}`;
                    } else if (filterData.min != null) {
                        return `${metricLabel}: ${iconHTML} ${filterData.min}`;
                    } else if (filterData.max != null) {
                        return `${metricLabel}: ${iconHTML} ${filterData.max}`;
                    }
                }
                return `${metricLabel}: ${match.label}`;
            }
        }
        const condition = filterData.condition || "between";
        const conditionConfig = this.CONDITIONS[condition];
        if (!conditionConfig) {
            return metricLabel;
        }
        const svgId = conditionConfig.svg_id;
        const iconHTML = `<svg width="18" height="18" fill="none" stroke="currentColor"><use href="#${svgId}"></use></svg>`;
        if (filterData.min != null && filterData.max != null) {
            return `${metricLabel}: ${iconHTML} ${filterData.min} to ${filterData.max}`;
        } else if (filterData.min != null) {
            return `${metricLabel}: ${iconHTML} ${filterData.min}`;
        } else if (filterData.max != null) {
            return `${metricLabel}: ${iconHTML} ${filterData.max}`;
        } else if (filterData.value != null) {
            return `${metricLabel}: ${iconHTML} ${filterData.value}`;
        }
        return metricLabel;
    }
    #setupGlobalEventListeners() {
        if (this.dom.addFilterBtn) {
            this.dom.addFilterBtn.addEventListener("click", () => this.#showAvailableFilters());
        }
        this.rootNode.addEventListener("click", e => {
            if (e.target.closest(".reset-all-filters-btn")) {
                this.#resetAllFilters();
            }
        });
        this.rootNode.addEventListener("click", e => {
            if (e.target.closest(".remove-all-filters-btn")) {
                this.#removeAllFilters();
            }
        });
    }
    #handlePrimaryToggleChange(isChecked) {
        this.state.isPrimary = isChecked;
        this.#savePrimaryToggleState();
        this.#updatePrimaryIconVisibility();
    }
    #attachPrimaryToggleEvents() {
        const checkbox = this.rootNode.querySelector(".primary-checkbox");
        const label = this.rootNode.querySelector(".primary-label");
        const toggle = this.rootNode.querySelector(".primary-toggle");
        const footerRow = this.rootNode.querySelector(".select-footer > div");
        if (!checkbox) return;
        const newCheckbox = checkbox.cloneNode(true);
        checkbox.parentNode.replaceChild(newCheckbox, checkbox);
        newCheckbox.addEventListener("change", e => {
            e.stopPropagation();
            const isChecked = e.target.checked;
            this.state.isPrimary = isChecked;
            this.#savePrimaryToggleState();
            this.#updatePrimaryIconVisibility();
            this.#applyFiltersToScreener();
        });
        if (footerRow) {
            footerRow.style.cursor = "pointer";
            footerRow.addEventListener("click", e => {
                e.stopPropagation();
                const cb = this.rootNode.querySelector(".primary-checkbox");
                if (cb) {
                    cb.checked = !cb.checked;
                    cb.dispatchEvent(new Event("change"));
                }
            });
        }
        [ newCheckbox, label ].forEach(el => {
            if (el) {
                el.addEventListener("click", e => e.stopPropagation());
            }
        });
    }
    #updatePrimaryIconVisibility() {
        const icon = this.rootNode.querySelector(".country-text-primary-icon");
        if (icon) {
            icon.style.display = this.state.isPrimary ? "" : "none";
        }
    }
    #showAvailableFilters() {
        const availableFilters = this.#getAvailableFiltersForSelection();
        if (!this.dom.filterSelectorList) return;
        this.dom.filterSelectorList.innerHTML = "";
        if (availableFilters.length === 0) {
            this.dom.filterSelectorList.innerHTML = '<li class="no-filters">All filters are already added</li>';
            return;
        }
        availableFilters.forEach(metric => {
            const optionHTML = `\n                <li class="select-option" data-search="${metric.tooltip}" data-filter-key="${metric.key}">\n                    ${metric.label}\n                </li>\n            `;
            this.dom.filterSelectorList.insertAdjacentHTML("beforeend", optionHTML);
        });
        this.#attachFilterSelectorEvents();
    }
    #getAvailableFiltersForSelection() {
        const activeFilterKeys = Object.keys(this.state.activeFilters);
        return this.state.availableMetrics.filter(metric => !activeFilterKeys.includes(metric.key));
    }
    #attachFilterSelectorEvents() {
        if (!this.dom.filterSelectorList) return;
        this.dom.filterSelectorList.querySelectorAll(".select-option").forEach(option => {
            option.addEventListener("click", e => {
                const filterKey = e.currentTarget.dataset.filterKey;
                this.#addNewFilter(filterKey);
            });
        });
    }
    #addNewFilter(filterKey) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric) return;
        const defaultValue = metric.filter_type === "select" ? {
            value: null
        } : {
            condition: "between",
            min: null,
            max: null,
            value: null
        };
        this.state.activeFilters[filterKey] = defaultValue;
        this.#renderFilterDropdown(metric, defaultValue);
        this.#saveFiltersToStorage();
    }
    #attachFilterItemEvents(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (!filterItem) {
            return;
        }
        const resetBtn = filterItem.querySelector(".reset-filter-btn-footer");
        if (resetBtn) {
            resetBtn.addEventListener("click", e => {
                e.stopPropagation();
                this.#resetSingleFilter(filterKey);
            });
        }
        const removeBtn = filterItem.querySelector(".remove-filter-btn");
        if (removeBtn) {
            removeBtn.addEventListener("click", e => {
                e.stopPropagation();
                this.#removeSingleFilter(filterKey);
            });
        }
        const manualBtn = filterItem.querySelector(".manual-filter-btn");
        if (manualBtn) {
            manualBtn.addEventListener("click", e => {
                e.stopPropagation();
                this.#openManualFilterInput(filterKey);
            });
        }
        const backBtn = filterItem.querySelector(".back-to-main-btn");
        if (backBtn) {
            backBtn.addEventListener("click", e => {
                e.stopPropagation();
                this.#backToMainView(filterKey);
            });
        }
        const selectTrigger = filterItem.querySelector(":scope > .dropdown-select > .select-trigger");
        if (selectTrigger) {
            selectTrigger.addEventListener("click", () => {
                requestAnimationFrame(() => {
                    const hasPredefined = filterItem.dataset.hasPredefined === "true";
                    if (hasPredefined) {
                        this.#backToMainView(filterKey);
                    }
                });
            });
        }
        const dropdown = filterItem.querySelector(":scope > .dropdown-select");
        const metric = this.#getMetricByKey(filterKey);
        if (dropdown && metric?.load_options_api) {
            const camelKey = filterKey.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
            const openListenerKey = "openListener" + camelKey.charAt(0).toUpperCase() + camelKey.slice(1);
            if (dropdown.dataset[openListenerKey] === "attached") {
                return;
            }
            dropdown.dataset[openListenerKey] = "attached";
            dropdown.addEventListener("customSelectOpen", () => {
                this.#handleApiOptionsOnOpen(filterKey, filterItem);
            });
        }
    }
    #attachSelectOptionEvents(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const metric = this.#getMetricByKey(filterKey);
        if (!metric || !filterItem) return;
        const dropdown = filterItem.querySelector(".dropdown-select");
        const isMultiple = metric.data_multiple === true;
        const maxSelected = metric.max_selected || null;
        if (isMultiple && dropdown) {
            const camelKey = filterKey.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
            const listenerKey = "changeListener" + camelKey.charAt(0).toUpperCase() + camelKey.slice(1);
            if (dropdown.dataset[listenerKey] === "attached") {
                return;
            }
            dropdown.dataset[listenerKey] = "attached";
            dropdown.addEventListener("customSelectChange", () => {
                const customSelectAPI = dropdown.customSelectAPI;
                if (customSelectAPI && typeof customSelectAPI.getValue === "function") {
                    const value = customSelectAPI.getValue();
                    if (maxSelected && Array.isArray(value) && value.length > maxSelected) {
                        const previousValue = this.state.activeFilters[filterKey]?.value || [];
                        customSelectAPI.setValue(previousValue, false);
                        return;
                    }
                    this.#updateFilterValue(filterKey, {
                        value: value
                    });
                    this.#updateMaxSelectedState(filterKey, value);
                }
            });
            return;
        }
        const optionsSelector = filterKey === "country" ? ".select-options .select-option" : ".select-body-main .select-option";
        filterItem.querySelectorAll(optionsSelector).forEach(option => {
            option.addEventListener("click", e => {
                const optionEl = e.currentTarget;
                if (metric.filter_type === "select") {
                    const value = optionEl.dataset.value;
                    this.#updateFilterValue(filterKey, {
                        value: value
                    });
                } else {
                    const min = optionEl.dataset.min !== undefined ? optionEl.dataset.min : null;
                    const max = optionEl.dataset.max !== undefined ? optionEl.dataset.max : null;
                    let condition = optionEl.dataset.condition;
                    if (!condition) {
                        if (min != null && max == null) {
                            condition = "above";
                        } else if (max != null && min == null) {
                            condition = "below";
                        } else {
                            condition = "between";
                        }
                    }
                    if (condition === "equal") {
                        const value = optionEl.dataset.value ?? min ?? max;
                        this.#updateFilterValue(filterKey, {
                            condition: condition,
                            value: value,
                            min: null,
                            max: null
                        });
                    } else {
                        this.#updateFilterValue(filterKey, {
                            condition: condition,
                            min: min,
                            max: max,
                            value: null
                        });
                    }
                    filterItem.querySelectorAll(".select-body-manual .manual-input").forEach(input => {
                        input.value = "";
                    });
                }
            });
        });
    }
    #updateFilterValue(filterKey, values) {
        if (filterKey === "country") {
            const metric = this.#getMetricByKey("country");
            const isMultiple = metric?.data_multiple === true;
            if (isMultiple) {
                let selectedValues = [];
                if (Array.isArray(values.value)) {
                    selectedValues = values.value;
                } else if (typeof values.value === "string") {
                    selectedValues = values.value ? values.value.split(",").filter(v => v) : [];
                } else if (values.value === null || values.value === undefined || values.value === "") {
                    selectedValues = [];
                }
                if (selectedValues.length === 0) {
                    const defaultCountry = this.screener?.CONFIG?.DEFAULT_COUNTRY || "US";
                    selectedValues = [ defaultCountry ];
                }
                values.value = selectedValues;
            } else {
                if (!values.value || values.value === "") {
                    const defaultCountry = this.screener?.CONFIG?.DEFAULT_COUNTRY || "US";
                    values.value = defaultCountry;
                }
            }
        }
        this.state.activeFilters[filterKey] = {
            ...this.state.activeFilters[filterKey],
            ...values
        };
        if (filterKey === "country" && values.value) {
            if (this.screener?.state) {
                this.screener.state.otherParams = this.screener.state.otherParams || {};
                this.screener.state.otherParams.country = values.value;
            }
            this.#resetExchangeFilter();
            this.#clearApiOptionsCacheForCountryDependentFilters();
            this.#updateCurrencyInManualFilters(values.value);
        }
        this.#updateFilterLabel(filterKey);
        this.#updateSelectedOptions(filterKey, values);
        this.#updateResetButtonVisibility(filterKey);
        this.#updateFilterActiveClass(filterKey);
        if (filterKey === "country") {
            const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
            const dropdown = filterItem?.querySelector(".dropdown-select");
            const customSelectAPI = dropdown?.customSelectAPI;
            if (customSelectAPI && typeof customSelectAPI.setValue === "function") {
                customSelectAPI.setValue(values.value, false);
            }
        }
        this.#saveFiltersToStorage();
        this.#applyFiltersToScreener();
    }
    #updateFilterLabel(filterKey) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric) return;
        const filterData = this.state.activeFilters[filterKey];
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const label = filterItem?.querySelector(".select-trigger-text-nochange");
        if (!label) {
            return;
        }
        try {
            if (filterKey === "country") {
                const labelHTML = this.#generateCountryLabel(filterData.value);
                label.innerHTML = labelHTML;
                if (typeof lazyLoadInstance !== "undefined" && lazyLoadInstance.update) {
                    lazyLoadInstance.update();
                }
            } else {
                const predefinedValues = FilterDataModule.getPredefinedValue(metric.key, this.state.category);
                const labelText = this.#getSelectedLabel(metric, filterData, predefinedValues);
                label.innerHTML = labelText;
            }
        } catch (error) {}
    }
    #generateCountryLabel(countryValue) {
        const metric = this.#getMetricByKey("country");
        const isMultiple = metric?.data_multiple === true;
        const countryOptions = FilterUtils.getNestedValue(this.marketData, "stock.country") || {};
        if (isMultiple) {
            const values = Array.isArray(countryValue) ? countryValue : countryValue ? countryValue.split(",") : [];
            if (values.length === 0) {
                return "Country";
            } else if (values.length === 1) {
                const code = values[0];
                const countryData = countryOptions[code];
                const countryName = countryData?.name || code;
                const allCountriesText = getLang("dropdowns.all_countries", "All countries");
                const displayText = code === "all" ? allCountriesText : countryName;
                return `\n                    <div class="flag-icon-container">\n                        <img data-src="${this.iconPath}country/${code}${this.iconType}" \n                             alt="${countryName}" class="flag-img">\n                    </div> \n                    ${displayText}\n                `;
            } else {
                return `\n                    <div class="flag-icon-container">\n                        <svg width="100%" height="100%" fill="none" stroke="currentColor">\n                            <use href="#global"></use>\n                        </svg>\n                    </div> \n                    Country <span class="select-trigger-text-count">${values.length}</span>\n                `;
            }
        } else {
            const countryCode = countryValue || "all";
            const countryData = countryOptions[countryCode];
            const countryName = countryData?.name || countryCode;
            const allCountriesText = getLang("dropdowns.all_countries", "All countries");
            const displayText = countryCode === "all" ? allCountriesText : countryName;
            return `\n                <div class="flag-icon-container">\n                    <img data-src="${this.iconPath}country/${countryCode}${this.iconType}" \n                         alt="${countryName}" class="flag-img">\n                </div> \n                ${displayText}\n            `;
        }
    }
    #updateSelectedOptions(filterKey, values) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const dropdown = filterItem?.querySelector(".dropdown-select");
        const metric = this.#getMetricByKey(filterKey);
        const customSelectAPI = dropdown?.customSelectAPI;
        if (customSelectAPI && typeof customSelectAPI.setValue === "function") {
            if (values.value != null) {
                customSelectAPI.setValue(values.value);
                if (metric?.data_multiple === true) {
                    this.#updateMaxSelectedState(filterKey, values.value);
                }
                return;
            }
        }
        const optionsContainer = filterKey === "country" ? ".select-body" : ".select-body-main";
        if (!filterItem) return;
        filterItem.querySelectorAll(`${optionsContainer} .select-option`).forEach(opt => {
            opt.classList.remove("selected");
        });
        if (values.value != null) {
            if (metric?.data_multiple === true) {
                const selectedValues = Array.isArray(values.value) ? values.value : values.value.split(",");
                selectedValues.forEach(val => {
                    const opt = filterItem.querySelector(`${optionsContainer} .select-option[data-value="${val}"]`);
                    if (opt) opt.classList.add("selected");
                });
            } else {
                const opt = filterItem.querySelector(`${optionsContainer} .select-option[data-value="${values.value}"]`);
                if (opt) opt.classList.add("selected");
            }
        } else if (values.min != null || values.max != null) {
            filterItem.querySelectorAll(`${optionsContainer} .select-option`).forEach(opt => {
                const optMin = opt.dataset.min;
                const optMax = opt.dataset.max;
                if (optMin == values.min && optMax == values.max) {
                    opt.classList.add("selected");
                }
            });
        }
    }
    #updateMaxSelectedState(filterKey, selectedValues) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric || !metric.max_selected) return;
        const maxSelected = metric.max_selected;
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (!filterItem) return;
        const optionsSelector = filterKey === "country" ? ".select-options .select-option" : ".select-body-main .select-option";
        const selectedArray = Array.isArray(selectedValues) ? selectedValues : selectedValues ? selectedValues.split(",") : [];
        const selectedCount = selectedArray.length;
        if (selectedCount >= maxSelected) {
            filterItem.querySelectorAll(optionsSelector).forEach(option => {
                const optionValue = option.dataset.value;
                if (!selectedArray.includes(optionValue)) {
                    option.classList.add("disabled");
                    option.setAttribute("disabled", "true");
                } else {
                    option.classList.remove("disabled");
                    option.removeAttribute("disabled");
                }
            });
        } else {
            filterItem.querySelectorAll(optionsSelector).forEach(option => {
                option.classList.remove("disabled");
                option.removeAttribute("disabled");
            });
        }
    }
    #updateResetButtonVisibility(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const filterData = this.state.activeFilters[filterKey];
        const metric = this.#getMetricByKey(filterKey);
        const resetBtn = filterItem?.querySelector(".reset-filter-btn-footer");
        if (!metric || !filterData || !resetBtn) {
            if (resetBtn) resetBtn.style.display = "none";
            return;
        }
        let hasValue = false;
        if (metric.filter_type === "select") {
            if (metric.data_multiple === true) {
                if (Array.isArray(filterData.value)) {
                    hasValue = filterData.value.length > 0;
                } else if (typeof filterData.value === "string") {
                    hasValue = filterData.value !== "" && filterData.value.split(",").filter(v => v).length > 0;
                }
            } else {
                hasValue = filterData.value != null && filterData.value !== "";
            }
        } else {
            hasValue = filterData.min != null || filterData.max != null || filterData.value != null;
        }
        resetBtn.style.display = hasValue ? "" : "none";
    }
    #resetSingleFilter(filterKey) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric) return;
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const dropdown = filterItem?.querySelector(".dropdown-select");
        const customSelectAPI = dropdown?.customSelectAPI;
        if (metric.filter_type === "select") {
            if (customSelectAPI && typeof customSelectAPI.setValue === "function") {
                customSelectAPI.setValue(null);
            }
            this.#updateFilterValue(filterKey, {
                value: null
            });
        } else {
            this.#updateFilterValue(filterKey, {
                condition: "between",
                min: null,
                max: null,
                value: null
            });
        }
        if (typeof CustomSelect !== "undefined" && CustomSelect.closeAll) {
            CustomSelect.closeAll(this.rootNode);
        }
    }
    #removeSingleFilter(filterKey) {
        delete this.state.activeFilters[filterKey];
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (filterItem) filterItem.remove();
        this.#saveFiltersToStorage();
        this.#applyFiltersToScreener();
    }
    #updateFilterActiveClass(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const dropdownSelect = filterItem?.querySelector(":scope > .dropdown-select");
        const filterData = this.state.activeFilters[filterKey];
        const metric = this.#getMetricByKey(filterKey);
        let isActive = false;
        if (filterData) {
            if (metric?.filter_type === "select" && metric?.data_multiple === true) {
                if (Array.isArray(filterData.value)) {
                    isActive = filterData.value.length > 0;
                } else if (typeof filterData.value === "string") {
                    isActive = filterData.value !== "" && filterData.value.split(",").filter(v => v).length > 0;
                }
            } else {
                isActive = filterData.value != null || filterData.min != null || filterData.max != null;
            }
        }
        if (dropdownSelect) {
            if (isActive) {
                dropdownSelect.classList.add("filter-active");
            } else {
                dropdownSelect.classList.remove("filter-active");
            }
        }
    }
    #resetAllFilters() {
        const filterPanel = this.dom.filterPanel;
        if (!filterPanel) return;
        const filterKeys = [];
        filterPanel.querySelectorAll(".filter-item").forEach(element => {
            const filterKey = element.dataset.filterKey;
            if (filterKey) filterKeys.push(filterKey);
        });
        filterKeys.forEach(filterKey => {
            const metric = this.#getMetricByKey(filterKey);
            if (!metric) return;
            if (metric.filter_type === "select") {
                if (filterKey === "country") {
                    const defaultCountry = this.screener?.CONFIG?.DEFAULT_COUNTRY || "all";
                    this.state.activeFilters[filterKey] = {
                        value: defaultCountry
                    };
                } else {
                    this.state.activeFilters[filterKey] = {
                        value: null
                    };
                }
            } else {
                this.state.activeFilters[filterKey] = {
                    condition: "between",
                    min: null,
                    max: null
                };
            }
        });
        requestAnimationFrame(() => {
            filterKeys.forEach(filterKey => {
                this.#updateFilterLabel(filterKey);
                this.#updateResetButtonVisibility(filterKey);
                this.#updateFilterActiveClass(filterKey);
                const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
                if (!filterItem) return;
                const optionsContainer = filterKey === "country" ? ".select-body" : ".select-body-main";
                filterItem.querySelectorAll(`${optionsContainer} .select-option`).forEach(opt => {
                    opt.classList.remove("selected");
                });
                if (filterKey === "country") {
                    const defaultCountry = this.screener?.CONFIG?.DEFAULT_COUNTRY || "all";
                    const defaultOpt = filterItem.querySelector(`${optionsContainer} .select-option[data-value="${defaultCountry}"]`);
                    if (defaultOpt) defaultOpt.classList.add("selected");
                }
                filterItem.querySelectorAll(".manual-input").forEach(input => {
                    input.value = "";
                });
            });
        });
        this.#saveFiltersToStorage();
        this.#applyFiltersToScreener();
    }
    #removeAllFilters() {
        const filterPanel = this.dom.filterPanel;
        if (!filterPanel) return;
        const filterKeys = [];
        Array.from(filterPanel.children).forEach(element => {
            if (element.classList.contains("filter-item")) {
                const filterKey = element.dataset.filterKey;
                if (filterKey) {
                    filterKeys.push(filterKey);
                    delete this.state.activeFilters[filterKey];
                }
                element.remove();
            }
        });
        this.#saveFiltersToStorage();
        this.#applyFiltersToScreener();
    }
    #openManualFilterInput(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (!filterItem) return;
        const selectBodyMain = filterItem.querySelector(".select-body-main");
        const selectBodyManual = filterItem.querySelector(".select-body-manual");
        const manualFilterBtn = filterItem.querySelector(".manual-filter-btn");
        const selectHeader = filterItem.querySelector(".select-header");
        const applyManualBtn = filterItem.querySelector(".apply-manual-btn");
        const resetFilterBtn = filterItem.querySelector(".reset-filter-btn-footer");
        if (selectBodyMain) selectBodyMain.style.display = "none";
        if (selectBodyManual) selectBodyManual.style.display = "";
        if (manualFilterBtn) manualFilterBtn.style.display = "none";
        if (selectHeader) selectHeader.style.display = "";
        if (applyManualBtn) applyManualBtn.style.display = "";
        if (resetFilterBtn) resetFilterBtn.style.display = "none";
        const conditionDropdown = filterItem.querySelector(".manual-condition-dropdown");
        if (conditionDropdown && !conditionDropdown.customSelectAPI) {
            if (typeof initCustomSelects === "function") {
                initCustomSelects(filterItem);
            }
        }
        const metric = this.#getMetricByKey(filterKey);
        const allowedConditions = this.#getAvailableConditions(metric);
        if (allowedConditions && allowedConditions.length > 0) {
            const filterData = this.state.activeFilters[filterKey];
            const predefinedValues = FilterDataModule.getPredefinedValue(metric.key, this.state.category);
            let isPredefinedMatch = false;
            if (predefinedValues && predefinedValues.length > 0 && filterData) {
                const filterMin = FilterUtils.normalizeValue(filterData.min);
                const filterMax = FilterUtils.normalizeValue(filterData.max);
                const filterCondition = filterData.condition;
                isPredefinedMatch = predefinedValues.some(opt => {
                    const optMin = FilterUtils.normalizeValue(opt.min);
                    const optMax = FilterUtils.normalizeValue(opt.max);
                    const optCondition = opt.condition || "between";
                    return optMin === filterMin && optMax === filterMax && optCondition === filterCondition;
                });
            }
            const selectedConditionEl = conditionDropdown?.querySelector(".select-option.selected");
            const currentCondition = selectedConditionEl?.dataset.condition || allowedConditions[0];
            let useFilterData = null;
            let useCondition = currentCondition;
            if (!isPredefinedMatch && filterData && (filterData.min != null || filterData.max != null || filterData.value != null)) {
                useFilterData = filterData;
                useCondition = filterData.condition || currentCondition;
                if (filterData.condition && conditionDropdown) {
                    conditionDropdown.querySelectorAll(".select-option").forEach(opt => opt.classList.remove("selected"));
                    const matchingOpt = conditionDropdown.querySelector(`.select-option[data-condition="${filterData.condition}"]`);
                    if (matchingOpt) matchingOpt.classList.add("selected");
                    const conditionConfig = this.CONDITIONS[filterData.condition];
                    if (conditionConfig) {
                        const triggerText = conditionDropdown.querySelector(".select-trigger-text");
                        if (triggerText) {
                            triggerText.innerHTML = `\n                                <span class="select-option-img">\n                                    <svg width="18" height="18" fill="none" stroke="currentColor">\n                                        <use href="#${conditionConfig.svg_id}"></use>\n                                    </svg>\n                                    ${conditionConfig.label}\n                                </span>\n                            `;
                        }
                    }
                }
            }
            const newInputsHTML = this.#generateInputFields(useCondition, metric, useFilterData);
            const manualInputs = filterItem.querySelector(".manual-inputs");
            if (manualInputs) {
                manualInputs.outerHTML = newInputsHTML;
            }
        }
        this.#attachManualInputEvents(filterKey, allowedConditions);
    }
    #getAvailableConditions(metric) {
        if (!metric) return false;
        if (metric.conditions !== undefined) {
            if (metric.conditions === false) return false;
            if (Array.isArray(metric.conditions)) return metric.conditions;
            if (metric.conditions === true) return Object.keys(this.CONDITIONS);
        }
        if (metric.filter_type === "select") return false;
        return FilterDataModule.getDefaultConditionsForMetric(metric.key);
    }
    #generateManualFilterUI(metric, allowedConditions, filterData = null) {
        if (!Array.isArray(allowedConditions) || allowedConditions.length === 0) {
            return "";
        }
        const savedCondition = filterData?.condition;
        const firstCondition = savedCondition && allowedConditions.includes(savedCondition) ? savedCondition : allowedConditions[0];
        const firstConditionLabel = this.CONDITIONS[firstCondition]?.label || "Between";
        const firstConditionSvg = this.CONDITIONS[firstCondition]?.svg_id || "between";
        let html = '<div class="manual-filter-container">';
        if (allowedConditions.length > 1) {
            html += '<div class="condition-selector">';
            html += `\n                <div class="dropdown-select nested-select manual-condition-dropdown no-auto-highlight">\n                    <div class="select-trigger">\n                        <span class="select-trigger-text">\n                            <span class="select-option-img">\n                                <svg width="18" height="18" fill="none" stroke="currentColor">\n                                    <use href="#${firstConditionSvg}"></use>\n                                </svg>\n                                ${firstConditionLabel}\n                            </span>\n                        </span>\n                        <svg width="18" height="18" class="select-arrow" fill="none" stroke="currentColor">\n                            <use href="#chevron-down"></use>\n                        </svg>\n                    </div>\n                    <div class="select-dropdown">\n                        <div class="select-body">\n                            <ul class="select-options">\n            `;
            allowedConditions.forEach(condKey => {
                if (this.CONDITIONS[condKey]) {
                    const condition = this.CONDITIONS[condKey];
                    const isSelected = condKey === firstCondition;
                    html += `\n                        <li class="select-option ${isSelected ? "selected" : ""}" data-condition="${condKey}">\n                            <span class="select-option-img">\n                                <svg width="18" height="18" fill="none" stroke="currentColor">\n                                    <use href="#${condition.svg_id}"></use>\n                                </svg>\n                                ${condition.label}\n                            </span>\n                        </li>\n                    `;
                }
            });
            html += `\n                            </ul>\n                        </div>\n                    </div>\n                </div>\n            `;
            html += "</div>";
        }
        html += this.#generateInputFields(firstCondition, metric, filterData);
        html += "</div>";
        return html;
    }
    #generateInputFields(conditionKey, metric, filterData = null) {
        const condition = this.CONDITIONS[conditionKey];
        if (!condition) return "";
        let currency = metric.currency || "";
        const selectedCountry = this.state.activeFilters["country"]?.value;
        if (selectedCountry) {
            const COUNTRIES = FilterUtils.getNestedValue(this.marketData, "stock.country") || {};
            const countryData = COUNTRIES[selectedCountry];
            if (countryData && countryData.currency) {
                currency = countryData.currency;
            }
        }
        if (this.state.category === "forex" && currency === "USD") {
            currency = "";
        }
        const suffix = metric.suffix || "";
        const enterText = getLang("filters.ui.enter", "Enter");
        const placeholder = `${enterText} ${metric.label.toLowerCase()}`;
        const storedMin = filterData?.min ?? "";
        const storedMax = filterData?.max ?? "";
        const storedValue = filterData?.value ?? "";
        let html = `<div class="manual-inputs" data-condition="${conditionKey}">`;
        if (condition.api_format === "single") {
            const inputType = condition.inputs;
            const inputValue = inputType === "min" ? storedMin : inputType === "max" ? storedMax : storedValue;
            html += `\n                <div>\n                    <div class="input-wrapper">\n                        <input type="number" \n                               class="manual-input" \n                               data-input-type="${inputType}" \n                               placeholder="${placeholder}"\n                               value="${inputValue}"\n                               step="any">\n                        ${currency ? `<span class="input-prefix">${currency}</span>` : ""}\n                        ${suffix ? `<span class="input-suffix">${suffix}</span>` : ""}\n                    </div>\n                </div>\n            `;
        } else if (condition.api_format === "range") {
            html += `\n                <div class="input-group">\n                    <div class="input-wrapper">\n                        <input type="number"\n                               class="manual-input"\n                               data-input-type="min"\n                               placeholder="${getLang("filters.ui.from", "from")}"\n                               value="${storedMin}"\n                               step="any">\n                        ${currency ? `<span class="input-prefix">${currency}</span>` : ""}\n                        ${suffix ? `<span class="input-suffix">${suffix}</span>` : ""}\n                    </div>\n                </div>\n                <div class="input-group">\n                    <div class="input-wrapper">\n                        <input type="number"\n                               class="manual-input"\n                               data-input-type="max"\n                               placeholder="${getLang("filters.ui.to", "to")}"\n                               value="${storedMax}"\n                               step="any">\n                        ${currency ? `<span class="input-prefix">${currency}</span>` : ""}\n                        ${suffix ? `<span class="input-suffix">${suffix}</span>` : ""}\n                    </div>\n                </div>\n            `;
        }
        html += "</div>";
        return html;
    }
    #attachManualInputEvents(filterKey, allowedConditions) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        const metric = this.#getMetricByKey(filterKey);
        if (!metric || !filterItem) return;
        if (allowedConditions && allowedConditions.length > 0) {
            const conditionDropdown = filterItem.querySelector(".manual-condition-dropdown");
            if (conditionDropdown) {
                conditionDropdown.addEventListener("customSelectChange", e => {
                    const selectedConditionEl = e.target.querySelector(".select-option.selected");
                    const selectedCondition = selectedConditionEl?.dataset.condition;
                    if (selectedCondition) {
                        const newInputsHTML = this.#generateInputFields(selectedCondition, metric);
                        const manualInputs = filterItem.querySelector(".manual-inputs");
                        if (manualInputs) {
                            manualInputs.outerHTML = newInputsHTML;
                        }
                    }
                });
            }
        }
        const applyBtn = filterItem.querySelector(".apply-manual-btn");
        if (applyBtn) {
            applyBtn.addEventListener("click", e => {
                e.stopPropagation();
                this.#applyManualFilter(filterKey);
            });
        }
        filterItem.querySelectorAll(".manual-input").forEach(input => {
            input.addEventListener("click", e => e.stopPropagation());
            input.addEventListener("focus", e => e.stopPropagation());
            input.addEventListener("keypress", e => {
                if (e.which === 13 || e.key === "Enter") {
                    e.stopPropagation();
                    this.#applyManualFilter(filterKey);
                }
            });
        });
    }
    #applyManualFilter(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (!filterItem) return;
        const inputs = filterItem.querySelectorAll(".select-body-manual .manual-input");
        const selectedOptionEl = filterItem.querySelector(".manual-condition-dropdown .select-option.selected");
        const selectedCondition = selectedOptionEl?.dataset.condition || "between";
        const values = {
            condition: selectedCondition,
            min: null,
            max: null,
            value: null
        };
        inputs.forEach(input => {
            const inputType = input.dataset.inputType;
            const value = input.value;
            if (value !== "") {
                values[inputType] = FilterUtils.normalizeValue(value);
            }
        });
        this.#updateFilterValue(filterKey, values);
        const hasPredefined = filterItem.dataset.hasPredefined === "true";
        if (hasPredefined) {
            this.#backToMainView(filterKey);
        }
        if (typeof CustomSelect !== "undefined" && CustomSelect.closeAll) {
            CustomSelect.closeAll(this.rootNode);
        }
    }
    #backToMainView(filterKey) {
        const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
        if (!filterItem) return;
        const selectBodyManual = filterItem.querySelector(".select-body-manual");
        const selectBodyMain = filterItem.querySelector(".select-body-main");
        const selectHeader = filterItem.querySelector(".select-header");
        const applyManualBtn = filterItem.querySelector(".apply-manual-btn");
        const manualFilterBtn = filterItem.querySelector(".manual-filter-btn");
        if (selectBodyManual) selectBodyManual.style.display = "none";
        if (selectBodyMain) selectBodyMain.style.display = "";
        if (selectHeader) selectHeader.style.display = "none";
        if (applyManualBtn) applyManualBtn.style.display = "none";
        if (manualFilterBtn) manualFilterBtn.style.display = "";
        this.#updateResetButtonVisibility(filterKey);
    }
    #saveFiltersToStorage() {
        if (this.screener?.CONFIG?.ENABLE_STORAGE === false) return;
        try {
            STORAGE.set(this.state.storageKey, this.state.activeFilters);
        } catch (e) {}
    }
    getFiltersForAPI() {
        const apiFilters = {
            filters: {},
            otherParams: {}
        };
        if (this.state.isPrimary && this.assetType == "stock") {
            apiFilters.otherParams.is_primary = 1;
        }
        Object.entries(this.state.activeFilters).forEach(([filterKey, filterData]) => {
            const metric = this.state.availableMetrics.find(m => m?.key === filterKey);
            if (!metric || !metric.path) return;
            const apiKey = metric.path;
            if (metric.filter_type === "select") {
                if (filterData.value != null && filterData.value !== "") {
                    apiFilters.filters[apiKey + "_eq"] = filterData.value;
                }
                return;
            }
            const condition = filterData.condition || "between";
            const conditionConfig = this.CONDITIONS[condition];
            if (!conditionConfig) return;
            if (conditionConfig.api_format === "single") {
                const inputType = conditionConfig.inputs;
                const value = filterData[inputType];
                if (value != null) {
                    const operator = conditionConfig.operator;
                    apiFilters.filters[`${apiKey}${operator}`] = value;
                }
            } else if (conditionConfig.api_format === "range") {
                const minValue = filterData.min;
                const maxValue = filterData.max;
                if (minValue != null && maxValue != null) {
                    const operator = conditionConfig.operator;
                    apiFilters.filters[`${apiKey}${operator}`] = `${minValue},${maxValue}`;
                } else if (minValue != null) {
                    apiFilters.filters[`${apiKey}_gte`] = minValue;
                } else if (maxValue != null) {
                    apiFilters.filters[`${apiKey}_lte`] = maxValue;
                }
            }
        });
        return apiFilters;
    }
    #setFiltersToScreenerState() {
        const apiData = this.getFiltersForAPI();
        if (this.screener?.state) {
            this.screener.state.activeFilters = apiData.filters;
            this.screener.state.otherParams = apiData.otherParams;
        }
    }
    saveFiltersToStorage() {
        this.#saveFiltersToStorage();
    }
    #applyFiltersToScreener() {
        const apiData = this.getFiltersForAPI();
        if (this.screener?.state) {
            this.screener.state.activeFilters = apiData.filters;
            this.screener.state.otherParams = apiData.otherParams;
            if (typeof this.screener.reload === "function") {
                this.screener.reload();
            }
        }
    }
    updateExchangeOptions() {
        this.#updateExchangeOnDataChange();
    }
    #clearApiOptionsCacheForCountryDependentFilters() {
        for (const metric of this.state.availableMetrics) {
            if (metric?.load_options_api?.dynamic_params?.country) {
                const filterKey = metric.key;
                delete this.state.apiOptionsCache[filterKey];
                this.state.apiOptionsLoading[filterKey] = false;
                if (this.state.activeFilters[filterKey]) {
                    this.state.activeFilters[filterKey] = {
                        value: null
                    };
                }
                const filterItem = this.rootNode.querySelector(`.filter-item[data-filter-key="${filterKey}"]`);
                if (filterItem) {
                    const selectOptions = filterItem.querySelector(".select-options");
                    if (selectOptions) {
                        const clickToLoadText = getLang("filters.ui.click_to_load", "Click to load options");
                        selectOptions.innerHTML = `<li class="select-option disabled api-load-placeholder">${clickToLoadText}</li>`;
                    }
                    this.#updateFilterLabel(filterKey);
                }
            }
        }
    }
    async #loadApiOptions(filterKey) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric?.load_options_api) {
            return null;
        }
        if (this.state.apiOptionsCache[filterKey]) {
            return this.state.apiOptionsCache[filterKey];
        }
        if (this.state.apiOptionsLoading[filterKey]) {
            return null;
        }
        this.state.apiOptionsLoading[filterKey] = true;
        const apiConfig = metric.load_options_api;
        try {
            const apiUrl = `${API_ENDPOINT}${apiConfig.endpoint}`;
            const params = {
                ...apiConfig.params || {}
            };
            if (apiConfig.dynamic_params) {
                for (const [paramKey, filterSourceKey] of Object.entries(apiConfig.dynamic_params)) {
                    const filterValue = this.state.activeFilters[filterSourceKey]?.value;
                    if (filterValue) {
                        params[paramKey] = Array.isArray(filterValue) ? filterValue[0] : filterValue;
                    } else {
                        this.state.apiOptionsLoading[filterKey] = false;
                        const selectFirstText = getLang("filters.ui.select_country_first", "Please select a country first");
                        return {
                            _error: true,
                            message: selectFirstText
                        };
                    }
                }
            }
            const response = await sendPostRequest(apiUrl, params);
            if (!response || response.status === false) {
                throw new Error(response?.msg || "API request failed");
            }
            let data = response;
            if (apiConfig.response_path) {
                const pathParts = apiConfig.response_path.split(".");
                for (const part of pathParts) {
                    data = data?.[part];
                }
            }
            if (!Array.isArray(data)) {
                throw new Error("Invalid response format");
            }
            if (apiConfig.filter_condition) {
                const {key: key, operator: operator, value: value} = apiConfig.filter_condition;
                data = data.filter(item => {
                    const itemValue = key.split(".").reduce((acc, part) => acc?.[part], item);
                    const numValue = Number(itemValue) || 0;
                    switch (operator) {
                      case ">":
                        return numValue > value;

                      case ">=":
                        return numValue >= value;

                      case "<":
                        return numValue < value;

                      case "<=":
                        return numValue <= value;

                      case "===":
                        return itemValue === value;

                      case "!==":
                        return itemValue !== value;

                      default:
                        return true;
                    }
                });
            }
            const getNestedValue = (obj, path) => {
                if (!path) return null;
                return path.split(".").reduce((acc, part) => acc?.[part], obj);
            };
            const options = {};
            data.forEach(item => {
                const value = getNestedValue(item, apiConfig.value_key) || item.id || item.name;
                const label = getNestedValue(item, apiConfig.label_key) || item.name || value;
                const iconValue = apiConfig.icon_key ? getNestedValue(item, apiConfig.icon_key) : null;
                if (value) {
                    options[value] = {
                        label: label,
                        value: value,
                        icon: iconValue,
                        icon_base_path: apiConfig.icon_base_path
                    };
                }
            });
            this.state.apiOptionsCache[filterKey] = options;
            this.state.apiOptionsLoading[filterKey] = false;
            return options;
        } catch (error) {
            this.state.apiOptionsLoading[filterKey] = false;
            return null;
        }
    }
    async #handleApiOptionsOnOpen(filterKey, filterItem) {
        const metric = this.#getMetricByKey(filterKey);
        if (!metric?.load_options_api) {
            return;
        }
        const selectOptions = filterItem.querySelector(".select-options");
        if (!selectOptions) {
            return;
        }
        const loadingText = getLang("filters.ui.loading", "Loading...");
        const errorText = getLang("filters.ui.load_error", "Failed to load options");
        const noOptionsText = getLang("filters.ui.no_options", "No options available");
        if (this.state.apiOptionsCache[filterKey]) {
            return;
        }
        selectOptions.innerHTML = `<li class="select-option loading-option disabled"><span class="spinner-small"></span> ${loadingText}</li>`;
        const options = await this.#loadApiOptions(filterKey);
        if (options?._error) {
            selectOptions.innerHTML = `<li class="select-option disabled">${options.message}</li>`;
            return;
        }
        if (!options || Object.keys(options).length === 0) {
            selectOptions.innerHTML = `<li class="select-option disabled">${options === null ? errorText : noOptionsText}</li>`;
            return;
        }
        const filterData = this.state.activeFilters[filterKey] || {
            value: null
        };
        const optionsResult = this.#generateApiOptionsHTML(filterKey, options, filterData);
        selectOptions.innerHTML = optionsResult.html;
        const dropdown = filterItem.querySelector(".dropdown-select");
        if (dropdown?.customSelectAPI) {
            dropdown.customSelectAPI.refresh();
        }
        this.#attachSelectOptionEvents(filterKey);
    }
    #generateApiOptionsHTML(filterKey, options, filterData) {
        const metric = this.#getMetricByKey(filterKey);
        const isMultiple = metric?.data_multiple === true;
        let selectedValues = [];
        if (isMultiple && filterData?.value) {
            selectedValues = Array.isArray(filterData.value) ? filterData.value : filterData.value.split(",");
        }
        const optionsArray = Object.entries(options);
        const optionsCount = optionsArray.length;
        const optionsHTML = optionsArray.map(([key, value]) => {
            const optionValue = value?.value || key;
            const optionLabel = value?.label || key;
            const optionIcon = value?.icon || null;
            const iconBasePath = value?.icon_base_path;
            let isSelected = false;
            if (isMultiple) {
                isSelected = selectedValues.includes(optionValue);
            } else {
                isSelected = filterData?.value === optionValue;
            }
            if (optionIcon) {
                let iconSrc;
                if (iconBasePath === "" || iconBasePath === undefined) {
                    iconSrc = `${this.iconPath}${optionIcon}${this.iconType}`;
                } else {
                    iconSrc = `${this.iconPath}${iconBasePath}${optionIcon}${this.iconType}`;
                }
                return `\n                    <li class="select-option ${isSelected ? "selected" : ""}" data-value="${optionValue}">\n                        <span class="select-option-img">\n                            <div class="flag-icon-container">\n                                <img data-src="${iconSrc}" alt="${optionLabel}" class="flag-img">\n                            </div>\n                            ${optionLabel}\n                        </span>\n                    </li>\n                `;
            }
            return `\n                <li class="select-option ${isSelected ? "selected" : ""}" data-value="${optionValue}">\n                    ${optionLabel}\n                </li>\n            `;
        }).join("");
        return {
            html: optionsHTML,
            count: optionsCount
        };
    }
}