import { initializeTooltips } from "../components/custom-tooltip.js";

function applyTheme(theme) {
    const html = document.documentElement;
    html.classList.add("theme-transitioning");
    html.setAttribute("data-theme", theme);
    html.setAttribute("data-bs-theme", theme);
    try {
        STORAGE.set("theme", theme);
    } catch (_) {}
    html.offsetHeight;
    requestAnimationFrame(() => html.classList.remove("theme-transitioning"));
}

function toggleTheme() {
    const isDark = document.documentElement.getAttribute("data-theme") === "dark";
    const next = isDark ? "light" : "dark";
    applyTheme(next);
    return next;
}

function initializeTheme() {
    const themeToggle = document.getElementById("themeToggle");
    const mobileThemeToggle = document.getElementById("mobileThemeToggle");
    const savedTheme = STORAGE.get("theme") || "light";
    if (savedTheme === "dark") {
        document.documentElement.setAttribute("data-theme", savedTheme);
        document.documentElement.setAttribute("data-bs-theme", savedTheme);
        if (themeToggle) themeToggle.checked = true;
        if (mobileThemeToggle) mobileThemeToggle.checked = true;
    }
    const handleThemeChange = function(checked, sourceToggle) {
        applyTheme(checked ? "dark" : "light");
        if (themeToggle && themeToggle !== sourceToggle) themeToggle.checked = checked;
        if (mobileThemeToggle && mobileThemeToggle !== sourceToggle) mobileThemeToggle.checked = checked;
    };
    if (themeToggle) {
        themeToggle.addEventListener("change", function() {
            handleThemeChange(this.checked, this);
        });
    }
    if (mobileThemeToggle) {
        mobileThemeToggle.addEventListener("change", function() {
            handleThemeChange(this.checked, this);
        });
    }
}

function initializeSettingsDropdown() {
    if (window.__settingsDropdownInitialized) return;
    window.__settingsDropdownInitialized = true;
    const settingsToggle = document.getElementById("settingsToggle");
    const settingsMenu = document.getElementById("settingsMenu");
    if (!settingsToggle || !settingsMenu) return;
    const dropdown = settingsToggle.closest(".settings-dropdown");
    settingsToggle.addEventListener("click", function(e) {
        e.stopPropagation();
        const isOpen = dropdown.classList.contains("show");
        document.querySelectorAll(".nav-item.show").forEach(item => {
            item.classList.remove("show");
        });
        if (!isOpen) {
            dropdown.classList.add("show");
            settingsToggle.classList.add("active");
        } else {
            closeSettingsDropdown();
        }
    });
    const dropdownSub = settingsMenu.querySelector(".dropdown-sub");
    const langTrigger = settingsMenu.querySelector(".dropdown-item.has-sub");
    const dropdownMain = settingsMenu.querySelector(".dropdown-main");
    if (langTrigger && dropdownSub && dropdownMain) {
        langTrigger.addEventListener("mouseenter", function() {
            dropdownSub.classList.add("active");
        });
        dropdownMain.addEventListener("mouseover", function(e) {
            const target = e.target.closest(".dropdown-item");
            if (target && !target.classList.contains("has-sub")) {
                dropdownSub.classList.remove("active");
            }
        });
        settingsMenu.addEventListener("mouseleave", function() {
            dropdownSub.classList.remove("active");
        });
    }
    const langItems = settingsMenu.querySelectorAll(".lang-switch-item");
    langItems.forEach(item => {
        item.addEventListener("click", function() {
            switchLanguage(this.dataset.lang);
        });
    });
    document.addEventListener("click", function(e) {
        if (!dropdown.contains(e.target)) {
            closeSettingsDropdown();
        }
    });
    document.addEventListener("keydown", function(e) {
        if (e.key === "Escape" && dropdown.classList.contains("show")) {
            closeSettingsDropdown();
        }
    });
    function closeSettingsDropdown() {
        dropdown.classList.remove("show");
        settingsToggle.classList.remove("active");
        if (dropdownSub) {
            dropdownSub.classList.remove("active");
        }
    }
}

export function switchLanguage(newLang) {
    const defaultLang = "en";
    const availableLangs = AVAILABLE_LANGS;
    const baseUrl = typeof BASE_URL !== "undefined" ? BASE_URL : window.location.origin + "/";
    const baseUrlPath = new URL(baseUrl).pathname.replace(/\/$/, "");
    const currentPath = window.location.pathname;
    let pagePath = currentPath;
    if (currentPath.startsWith(baseUrlPath)) {
        pagePath = currentPath.substring(baseUrlPath.length);
    }
    pagePath = pagePath.replace(/^\//, "");
    const basePathParts = baseUrlPath.split("/").filter(p => p);
    const lastBasePart = basePathParts[basePathParts.length - 1];
    let cleanBasePath = baseUrlPath;
    if (availableLangs.includes(lastBasePart) && lastBasePart !== defaultLang) {
        cleanBasePath = "/" + basePathParts.slice(0, -1).join("/");
    }
    let newUrl;
    if (newLang === defaultLang) {
        newUrl = cleanBasePath + (pagePath ? "/" + pagePath : "/");
    } else {
        newUrl = cleanBasePath + "/" + newLang + (pagePath ? "/" + pagePath : "/");
    }
    newUrl = newUrl.replace(/\/+/g, "/");
    if (currentPath.endsWith("/") && !newUrl.endsWith("/")) {
        newUrl += "/";
    }
    window.location.href = newUrl;
}

const STORAGE = (() => {
    const cache = new Map;
    const keyIndex = new Set;
    let available = null;
    const checkAvailable = () => {
        if (available !== null) return available;
        try {
            const t = "__t__";
            localStorage.setItem(t, t);
            localStorage.removeItem(t);
            available = true;
        } catch (e) {
            available = false;
            console.warn("localStorage unavailable");
        }
        return available;
    };
    return {
        get(key) {
            if (cache.has(key)) {
                return cache.get(key);
            }
            if (!keyIndex.has(key) && !checkAvailable()) return null;
            try {
                const item = localStorage.getItem(key);
                if (!item) return null;
                let parsed;
                try {
                    parsed = JSON.parse(item);
                } catch (_) {
                    parsed = item;
                }
                cache.set(key, parsed);
                keyIndex.add(key);
                return parsed;
            } catch (e) {
                return null;
            }
        },
        set(key, value) {
            if (value == null) return false;
            cache.set(key, value);
            keyIndex.add(key);
            if (!checkAvailable()) return false;
            try {
                localStorage.setItem(key, JSON.stringify(value));
                return true;
            } catch (e) {
                if (e.name === "QuotaExceededError") {
                    this.clear();
                }
                return false;
            }
        },
        remove(key) {
            cache.delete(key);
            keyIndex.delete(key);
            if (!checkAvailable()) return false;
            try {
                localStorage.removeItem(key);
                return true;
            } catch (e) {
                return false;
            }
        },
        clear() {
            cache.clear();
            keyIndex.clear();
            if (!checkAvailable()) return false;
            try {
                localStorage.clear();
                return true;
            } catch (e) {
                return false;
            }
        },
        has(key) {
            return cache.has(key) || keyIndex.has(key);
        },
        setMultiple(obj) {
            if (!checkAvailable()) return false;
            Object.entries(obj).forEach(([k, v]) => this.set(k, v));
            return true;
        },
        getMultiple(keys) {
            return keys.reduce((acc, k) => {
                acc[k] = this.get(k);
                return acc;
            }, {});
        }
    };
})();

function showNotification(message, type = "info", duration = 3e3) {
    if (!message) return;
    let container = document.getElementById("notificationContainer");
    if (!container) {
        container = document.createElement("div");
        container.id = "notificationContainer";
        container.className = "notification-container";
        document.body.appendChild(container);
    }
    const notificationId = "notification_" + Date.now();
    const typeClass = type === "success" ? "notification-success" : type === "warning" ? "notification-warning" : type === "error" ? "notification-error" : "notification-info";
    const notification = document.createElement("div");
    notification.id = notificationId;
    notification.className = `notification ${typeClass}`;
    notification.setAttribute("role", "alert");
    notification.innerHTML = `\n        <span>${message}</span>\n        <button type="button" class="notification-close" aria-label="Close">\n            <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">\n                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>\n            </svg>\n        </button>\n    `;
    notification.querySelector(".notification-close").addEventListener("click", () => {
        removeNotification(notification);
    });
    container.appendChild(notification);
    if (duration !== false) {
        setTimeout(() => {
            removeNotification(document.getElementById(notificationId));
        }, duration);
    }
}

function removeNotification(notif) {
    if (!notif) return;
    notif.style.transition = "opacity 0.3s, transform 0.3s";
    notif.style.opacity = "0";
    notif.style.transform = "translateX(100%)";
    setTimeout(() => {
        if (notif.parentNode) {
            notif.parentNode.removeChild(notif);
        }
    }, 300);
}

function convertNumberToShortForm(value, is_fixed = false, desimal_places = 2) {
    if (value === null || value === undefined) return "—";
    const num = parseFloat(value);
    if (isNaN(num)) return value;
    const absNum = Math.abs(num);
    let formatted;
    switch (true) {
      case absNum >= 1e12:
        formatted = (num / 1e12).toFixed(2) + "T";
        break;

      case absNum >= 1e9:
        formatted = (num / 1e9).toFixed(2) + "B";
        break;

      case absNum >= 1e6:
        formatted = (num / 1e6).toFixed(2) + "M";
        break;

      case absNum >= 1e3:
        formatted = (num / 1e3).toFixed(2) + "K";
        break;

      default:
        formatted = is_fixed ? num.toFixed(desimal_places) : num;
    }
    return formatted;
}

function addThousandSeparator(price) {
    if (price === "null" || price === null || price === undefined || price === "undefined") return "—";
    const str = String(price);
    const dotIndex = str.indexOf(".");
    if (dotIndex === -1) {
        return str.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    return str.slice(0, dotIndex).replace(/\B(?=(\d{3})+(?!\d))/g, ",") + str.slice(dotIndex);
}

function initializeTableScrollShadows(selector = ".fx-table-scroll-shadow", root = document) {
    const target = root.querySelector(selector);
    if (!target || target.classList.contains("shadow-initialized")) return;
    const tables = target.querySelectorAll(".table-responsive");
    if (!tables.length) return;
    target.classList.add("shadow-initialized");
    tables.forEach(container => {
        const isRTL = getComputedStyle(container).direction === "rtl";
        const updateShadows = () => {
            let scroll = container.scrollLeft;
            const maxScroll = container.scrollWidth - container.clientWidth;
            if (maxScroll <= 0) {
                target.classList.remove("has-sticky-shadow", "at-scroll-end");
                return;
            }
            if (isRTL) scroll = Math.abs(scroll);
            const atStart = scroll <= 5;
            const atEnd = scroll >= maxScroll - 5;
            target.classList.toggle("has-sticky-shadow", !atStart);
            target.classList.toggle("at-scroll-end", !atEnd);
        };
        const initShadows = () => {
            requestAnimationFrame(() => {
                requestAnimationFrame(updateShadows);
            });
        };
        if (document.readyState === "complete") {
            initShadows();
        } else {
            window.addEventListener("load", initShadows, {
                once: true
            });
        }
        if (typeof ResizeObserver !== "undefined") {
            new ResizeObserver(updateShadows).observe(container);
        }
        container.addEventListener("scroll", updateShadows, {
            passive: true
        });
    });
}

function scrollToCenter(clickedElement, container) {
    const elem = clickedElement && clickedElement.jquery ? clickedElement[0] : clickedElement;
    const cont = container && container.jquery ? container[0] : container;
    if (!elem || !cont) return;
    if (cont.scrollWidth <= cont.clientWidth) return;
    const elemRect = elem.getBoundingClientRect();
    const contRect = cont.getBoundingClientRect();
    const elemCenter = (elemRect.left + elemRect.right) / 2;
    const contCenter = (contRect.left + contRect.right) / 2;
    const scrollLeft = cont.scrollLeft + (elemCenter - contCenter);
    cont.scrollTo({
        left: scrollLeft,
        behavior: "smooth"
    });
}

function getValueStyle(value, returnType = null) {
    let colorClass = "fx-neutral";
    let icon = "minus";
    if (value == null || value === "") {
        return returnType === "class" ? colorClass : returnType === "icon" ? icon : {
            class: colorClass,
            icon: icon
        };
    }
    const numValue = parseFloat(value);
    if (!isNaN(numValue)) {
        if (numValue > 0) {
            colorClass = "fx-positive";
            icon = "chevron-up";
        } else if (numValue < 0) {
            colorClass = "fx-negative";
            icon = "chevron-down";
        }
    } else {
        const textValue = String(value).toLowerCase().trim();
        if (textValue.includes("strong buy") || textValue.includes("strongbuy")) {
            colorClass = "fx-positive";
            icon = "strong-buy";
        } else if (textValue.includes("strong sell") || textValue.includes("strongsell")) {
            colorClass = "fx-negative";
            icon = "strong-sell";
        } else if (textValue.includes("buy")) {
            colorClass = "fx-positive";
            icon = "chevron-up";
        } else if (textValue.includes("sell")) {
            colorClass = "fx-negative";
            icon = "chevron-down";
        }
    }
    if (returnType === "class") {
        return colorClass;
    } else if (returnType === "icon") {
        return icon;
    } else {
        return {
            class: colorClass,
            icon: icon
        };
    }
}

function generateCoinLogoHtml(profile, rank = null) {
    const baseLogo = profile?.self_logo || profile?.base_logo || "";
    let currLogo = profile?.self_logo ? "" : profile?.curr_logo;
    if (baseLogo !== "" && currLogo === "country/US") currLogo = "";
    let logoHtml = "";
    if (baseLogo || currLogo) {
        const primaryLogo = baseLogo || currLogo;
        const hasSecondary = baseLogo && currLogo;
        logoHtml += `<div class="coin-image primary-coin"><img data-src="${ICON_PATH}${primaryLogo}${ICON_TYPE}" class="coin-img" alt="${primaryLogo}">`;
        if (rank) {
            logoHtml += `<span class="rank-badge">#${rank}</span>`;
        }
        logoHtml += "</div>";
        if (hasSecondary && profile?.type !== "coin") {
            logoHtml += `<div class="coin-image secondary-coin"><img data-src="${ICON_PATH}${currLogo}${ICON_TYPE}" class="coin-img" alt="${currLogo}"></div>`;
        }
    }
    return logoHtml;
}

function formatDateTime(timestamp, use24Hour = false) {
    let updateTime;
    if (typeof timestamp === "number") {
        updateTime = new Date(timestamp * 1e3);
    } else if (typeof timestamp === "string") {
        updateTime = new Date(timestamp);
    } else {
        return "Invalid date";
    }
    const now = new Date;
    const isToday = updateTime.toDateString() === now.toDateString();
    const timeOptions = {
        hour: "2-digit",
        minute: "2-digit",
        timeZoneName: "short",
        hour12: !use24Hour
    };
    if (isToday) {
        return updateTime.toLocaleTimeString("en-US", timeOptions);
    } else {
        return updateTime.toLocaleDateString("en-US", {
            month: "short",
            day: "numeric",
            ...timeOptions
        });
    }
}

function formatDate(input) {
    let date;
    if (typeof input === "number") {
        const milliseconds = input.toString().length === 10 ? input * 1e3 : input;
        date = new Date(milliseconds);
    } else if (typeof input === "string") {
        date = new Date(input);
        if (isNaN(date.getTime())) {
            const parts = input.match(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/);
            if (parts) {
                const day = parts[1];
                const month = parts[2];
                const year = parts[3];
                date = new Date(`${year}-${month}-${day}`);
            }
        }
    } else {
        date = new Date(input);
    }
    if (isNaN(date.getTime())) {
        return "Invalid Date";
    }
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
}

function smartSearch(inputSelector, searchContainerSelector, itemsSelector = null, parentSelector = null, searchAttr = null, rootNode = null) {
    const root = rootNode || document;
    const input = root.querySelector(inputSelector);
    if (!input) {
        console.error("Input element nahi mila:", inputSelector);
        return;
    }
    const searchContainer = root.querySelector(searchContainerSelector);
    if (!searchContainer) {
        console.error("Search container nahi mila:", searchContainerSelector);
        return;
    }
    const clearButton = document.createElement("button");
    clearButton.type = "button";
    clearButton.className = "search-html-clear-btn";
    clearButton.innerHTML = '<svg width="18" height="18" fill="none" stroke="currentColor"><use href="#x"></use></svg>';
    clearButton.style.display = "none";
    input.parentElement.appendChild(clearButton);
    const noResultsDiv = document.createElement("div");
    noResultsDiv.className = "no-results";
    noResultsDiv.innerHTML = `\n        <div class="no-results-icon">\n            <svg width="55" height="55" fill="none" stroke="currentColor">\n                <use href="#search-error"></use>\n            </svg>\n        </div>\n        <div>${getLang("custom_select.no_results", "No results found")}</div>\n    `;
    noResultsDiv.style.display = "none";
    searchContainer.appendChild(noResultsDiv);
    function getItems() {
        if (itemsSelector) {
            return searchContainer.querySelectorAll(itemsSelector);
        } else {
            return Array.from(searchContainer.children).filter(child => !child.classList.contains("no-results"));
        }
    }
    function clearSearch() {
        input.value = "";
        clearButton.style.display = "none";
        noResultsDiv.style.display = "none";
        getItems().forEach(item => item.style.display = "");
        if (parentSelector) {
            searchContainer.querySelectorAll(parentSelector).forEach(parent => {
                parent.style.display = "";
            });
        }
        input.focus();
    }
    clearButton.addEventListener("click", clearSearch);
    input.addEventListener("input", function() {
        const searchTerm = this.value.toLowerCase().trim();
        clearButton.style.display = searchTerm !== "" ? "" : "none";
        if (searchTerm === "") {
            noResultsDiv.style.display = "none";
            getItems().forEach(item => item.style.display = "");
            if (parentSelector) {
                searchContainer.querySelectorAll(parentSelector).forEach(parent => {
                    parent.style.display = "";
                });
            }
            return;
        }
        const items = getItems();
        let hasAnyVisibleItem = false;
        items.forEach(item => {
            const itemText = item.textContent.toLowerCase();
            let attrValue = "";
            if (searchAttr) {
                attrValue = (item.getAttribute(searchAttr) || "").toLowerCase();
            }
            const matchFound = itemText.includes(searchTerm) || searchAttr && attrValue.includes(searchTerm);
            if (matchFound) {
                item.style.display = "";
                hasAnyVisibleItem = true;
            } else {
                item.style.display = "none";
            }
        });
        if (parentSelector) {
            searchContainer.querySelectorAll(parentSelector).forEach(parent => {
                const itemsInParent = parent.querySelectorAll(itemsSelector || "*");
                let hasVisibleItem = false;
                itemsInParent.forEach(childItem => {
                    const isVisible = window.getComputedStyle(childItem).display !== "none";
                    const isInItems = Array.from(items).includes(childItem);
                    if (isVisible && isInItems) {
                        hasVisibleItem = true;
                    }
                });
                parent.style.display = hasVisibleItem ? "" : "none";
            });
        }
        noResultsDiv.style.display = !hasAnyVisibleItem ? "" : "none";
    });
}

function getMarketStatus(isOpen, inputValue, langStrings = {}) {
    const atClose = langStrings.at_close || "At close,";
    const asOfToday = langStrings.as_of_today || "As of today,";
    const asOf = langStrings.as_of || "As of,";
    if (!isOpen) {
        return atClose;
    }
    const now = new Date;
    const todayStr = now.toISOString().slice(0, 10);
    let inputDate;
    if (!isNaN(inputValue)) {
        inputDate = new Date(inputValue * 1e3);
    } else {
        inputDate = new Date(inputValue);
    }
    const inputDateStr = inputDate.toISOString().slice(0, 10);
    if (inputDateStr === todayStr) {
        return asOfToday;
    } else {
        return asOf;
    }
}

function initFaqAccordion() {
    const faqItems = document.querySelectorAll(".faq-item");
    if (!faqItems.length) return;
    for (let i = 0; i < faqItems.length; i++) {
        const item = faqItems[i];
        const question = item.querySelector(".faq-question");
        if (question) {
            question.addEventListener("click", () => {
                const container = item.closest(".faq-accordion");
                if (container) {
                    const siblings = container.querySelectorAll(".faq-item");
                    for (let j = 0; j < siblings.length; j++) {
                        if (siblings[j] !== item) {
                            siblings[j].classList.remove("active");
                        }
                    }
                }
                item.classList.toggle("active");
            });
        }
    }
}

function parseParamsFromElement(element, baseColumns = null) {
    if (!element) return {};
    const paramNames = element.dataset.paramName;
    const paramValues = element.dataset.paramValue;
    if (!paramNames || !paramValues) return {};
    const names = paramNames.split(",");
    const values = paramValues.split(",");
    const params = {};
    for (let i = 0; i < names.length; i++) {
        const name = names[i]?.trim();
        let value = values[i]?.trim();
        if (!name) continue;
        if (value && (value.startsWith("{") || value.startsWith("["))) {
            try {
                value = JSON.parse(value);
            } catch (e) {}
        }
        if (name === "columns" && baseColumns !== null) {
            const baseArr = Array.isArray(baseColumns) ? baseColumns : baseColumns.split(",");
            if (!baseArr.includes(value)) {
                baseArr.push(value);
            }
            value = baseArr.join(",");
        }
        params[name] = value;
    }
    return params;
}

const STOCK_TYPES = [ "stock", "dr", "fund", "funds", "index", "indices" ];

function buildDynamicUrl(urlTemplate, values = {}) {
    const {symbol: symbol, exchange: exchange, type: type, path: path} = values;
    const baseUrl = typeof BASE_URL !== "undefined" ? BASE_URL : "/";
    if (!urlTemplate) {
        if (type && symbol && exchange) {
            if (STOCK_TYPES.includes(type)) {
                return `${baseUrl}symbols/${exchange}-${symbol}${path || ""}`;
            }
            return `${baseUrl}symbols/${symbol}${path || ""}?exchange=${exchange}`;
        }
        return "";
    }
    let url = urlTemplate;
    const basePath = typeof BASE_PATH !== "undefined" ? BASE_PATH : typeof window !== "undefined" && window.BASE_PATH ? window.BASE_PATH : baseUrl;
    if (url.includes("{{BASE_PATH}}")) {
        url = url.replace(/\{\{BASE_PATH\}\}/g, basePath.replace(/\/$/, ""));
    }
    if (url.includes("BASE_PATH")) {
        url = url.replace(/BASE_PATH/g, basePath.replace(/\/$/, ""));
    }
    if (url.includes("{{BASE_URL}}")) {
        url = url.replace(/\{\{BASE_URL\}\}/g, baseUrl.replace(/\/$/, ""));
    }
    if (url.includes("BASE_URL")) {
        url = url.replace(/BASE_URL/g, baseUrl.replace(/\/$/, ""));
    }
    Object.keys(values).forEach(key => {
        let value = values[key] || "";
        if (key === "name" && value) {
            value = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
        }
        const encoded = encodeURIComponent(value);
        const placeholder = `{{${key}}}`.replace(/[{}]/g, "\\$&");
        url = url.replace(new RegExp(placeholder, "g"), encoded);
    });
    url = url.replace(/\{\{[^}]+\}\}/g, "");
    url = url.replace(/([^:])\/\//g, "$1/").replace(/[-/]+$/, "");
    return url;
}

async function loadLang(fileName, storeKey = null) {
    const lang = window.CURRENT_LANG || "en";
    const version = (typeof VERSION !== "undefined" ? VERSION : "").replace(/^\?v=/, "");
    const versionQuery = version ? `?v=${version}` : "";
    const langUrl = `${window.JS_URL || "/assets/js/"}lang/${lang}/${fileName}.json${versionQuery}`;
    try {
        const response = await fetch(langUrl);
        if (response.ok) {
            const textContent = await response.text();
            const jsonData = JSON.parse(textContent);
            window.LANG = window.LANG || {};
            if (storeKey) {
                window.LANG[storeKey] = jsonData;
            } else {
                Object.assign(window.LANG, jsonData);
            }
            return jsonData;
        } else if (lang !== "en") {
            const fallbackUrl = `${window.JS_URL || "/assets/js/"}lang/en/${fileName}.json${versionQuery}`;
            const fallbackResponse = await fetch(fallbackUrl);
            if (fallbackResponse.ok) {
                const fallbackText = await fallbackResponse.text();
                const fallbackData = JSON.parse(fallbackText);
                window.LANG = window.LANG || {};
                if (storeKey) {
                    window.LANG[storeKey] = fallbackData;
                } else {
                    Object.assign(window.LANG, fallbackData);
                }
                return fallbackData;
            }
        }
    } catch (error) {}
    return null;
}

function getLang(path, fallback = "") {
    if (!path || typeof path !== "string") return fallback;
    const keys = path.split(".");
    let value = window.LANG;
    for (let i = 0; i < keys.length; i++) {
        const key = i === keys.length - 1 ? keys[i].toLowerCase() : keys[i];
        value = value?.[key];
        if (value === undefined) return fallback || keys[keys.length - 1];
    }
    return value || fallback || keys[keys.length - 1];
}

export { STORAGE, convertNumberToShortForm, addThousandSeparator, initializeTheme, applyTheme, toggleTheme, showNotification, initializeTableScrollShadows, scrollToCenter, initFaqAccordion, getValueStyle, generateCoinLogoHtml, formatDateTime, formatDate, smartSearch, getMarketStatus, buildDynamicUrl, STOCK_TYPES, parseParamsFromElement, loadLang, getLang };

if (typeof window !== "undefined") {
    window.STORAGE = STORAGE;
    window.convertNumberToShortForm = convertNumberToShortForm;
    window.addThousandSeparator = addThousandSeparator;
    window.initializeTheme = initializeTheme;
    window.applyTheme = applyTheme;
    window.toggleTheme = toggleTheme;
    window.showNotification = showNotification;
    window.initializeTableScrollShadows = initializeTableScrollShadows;
    window.scrollToCenter = scrollToCenter;
    window.initFaqAccordion = initFaqAccordion;
    window.getValueStyle = getValueStyle;
    window.generateCoinLogoHtml = generateCoinLogoHtml;
    window.formatDateTime = formatDateTime;
    window.formatDate = formatDate;
    window.smartSearch = smartSearch;
    window.getMarketStatus = getMarketStatus;
    window.buildDynamicUrl = buildDynamicUrl;
    window.parseParamsFromElement = parseParamsFromElement;
    window.getLang = getLang;
    window.loadLang = loadLang;
    window.switchLanguage = switchLanguage;
}

function helperInit() {
    initializeTheme();
    initializeSettingsDropdown();
    initializeTooltips();
    initFaqAccordion();
}

if (!document.querySelector('script[src*="vunelix-"]')) {
    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", helperInit);
    } else {
        helperInit();
    }
}