class MarketMovers {
    constructor(options = {}) {
        this.CONFIG = {
            CONTAINER: null,
            ROOT_NODE: document,
            API_TYPE: "forex",
            API_PARAMS: {
                type: "forex",
                per_page: 6
            },
            OBSERVER_THRESHOLD: .1,
            OBSERVER_ROOT_MARGIN: "100px",
            METRICS: [ "active.c", "active.chp" ],
            SHOW_SYMBOL: true,
            SHOW_NAME: true,
            SHOW_LOGO: true,
            SHOW_CURRENCY: true,
            CHANGE_BADGE: false,
            CARD_STYLE: "borderless",
            ENABLE_LINKS: true,
            LINK_URL: null,
            LINK_TARGET: "_self",
            sendPostRequest: null,
            addThousandSeparator: null,
            getValueStyle: null,
            generateCoinLogoHtml: null,
            buildDynamicUrl: null,
            apiEndpoint: null,
            webSocketInstance: null,
            ...options
        };
        if (!this.CONFIG.CONTAINER) {
            console.error("MarketMovers: CONTAINER is required");
            return;
        }
        const rootNode = this.CONFIG.ROOT_NODE || document;
        this.container = typeof this.CONFIG.CONTAINER === "string" ? rootNode.querySelector(this.CONFIG.CONTAINER) : this.CONFIG.CONTAINER;
        if (!this.container) {
            console.error("MarketMovers: Container not found:", this.CONFIG.CONTAINER);
            return;
        }
        this.apiEndpoint = this.CONFIG.apiEndpoint || (typeof API_ENDPOINT !== "undefined" ? API_ENDPOINT : "");
        this._sendPostRequest = this.CONFIG.sendPostRequest || (typeof sendPostRequest !== "undefined" ? sendPostRequest : null);
        this._addThousandSeparator = this.CONFIG.addThousandSeparator || (typeof addThousandSeparator !== "undefined" ? addThousandSeparator : null);
        this._getValueStyle = this.CONFIG.getValueStyle || (typeof getValueStyle !== "undefined" ? getValueStyle : null);
        this._generateCoinLogoHtml = this.CONFIG.generateCoinLogoHtml || (typeof generateCoinLogoHtml !== "undefined" ? generateCoinLogoHtml : null);
        this._buildDynamicUrl = this.CONFIG.buildDynamicUrl || (typeof buildDynamicUrl !== "undefined" ? buildDynamicUrl : null);
        this.state = {
            loading: false,
            data: []
        };
        this.gridContainer = this.container.querySelector(".market-movers-grid");
        this.observer = null;
        this.#init();
    }
    #init() {
        this.#setupObserver();
        this.#bindEvents();
    }
    #setupObserver() {
        this.observer = new IntersectionObserver(entries => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    this.#fetchData();
                    this.observer.disconnect();
                }
            });
        }, {
            threshold: this.CONFIG.OBSERVER_THRESHOLD,
            rootMargin: this.CONFIG.OBSERVER_ROOT_MARGIN
        });
        this.observer.observe(this.container);
    }
    #bindEvents() {}
    async #fetchData() {
        if (this.state.loading) return;
        this.state.loading = true;
        const postData = {
            columns: "profile.currency,profile.self_logo,active.c,active.ch,active.chp,profile.name,profile.symbol,profile.curr_logo,profile.base_logo,profile.exchange",
            ...this.CONFIG.API_PARAMS
        };
        try {
            const apiUrl = `${this.apiEndpoint}${this.CONFIG.API_TYPE}/advance`;
            const result = await this._sendPostRequest(apiUrl, postData);
            this.state.loading = false;
            const results = Array.isArray(result) ? result : result?.response || result?.data || [];
            this.state.data = results;
            this.#render(results);
        } catch (error) {
            this.state.loading = false;
            console.error("MarketMovers: Fetch error:", error);
            this.#showError();
        }
    }
    #render(data) {
        if (!this.gridContainer) return;
        this.container?.removeAttribute("aria-busy");
        if (!data || data.length === 0) {
            this.#showEmpty();
            return;
        }
        this.gridContainer.classList.remove("style-bordered", "style-borderless");
        this.gridContainer.classList.add(`style-${this.CONFIG.CARD_STYLE}`);
        const html = data.map(item => this.#renderCard(item)).join("");
        this.gridContainer.innerHTML = html;
        if (typeof window.LazyLoadRefresh === "function") {
            window.LazyLoadRefresh();
        }
        const wsInstance = this.CONFIG.webSocketInstance;
        if (wsInstance && typeof wsInstance.subscribeAllSymbols === "function") {
            wsInstance.subscribeAllSymbols();
        } else if (typeof webSocketService !== "undefined" && typeof webSocketService.subscribeAllSymbols === "function") {
            webSocketService.subscribeAllSymbols();
        }
    }
    #renderCard(item) {
        const profile = item.profile || {};
        const active = item.active || {};
        const perf = item.perf || {};
        const {symbol: symbol = "", name: name = "", exchange: exchange = "", currency: currency = ""} = profile;
        const ticker = item.ticker || `${exchange}:${symbol}`;
        const wsClass = ticker.replace(/[^a-zA-Z0-9]/g, "_");
        const logoHtml = this.CONFIG.SHOW_LOGO ? this._generateCoinLogoHtml(profile) : "";
        let cardUrl = "";
        if (this.CONFIG.ENABLE_LINKS) {
            const itemType = this.CONFIG.API_PARAMS?.type || this.CONFIG.API_TYPE || "forex";
            cardUrl = this._buildDynamicUrl(this.CONFIG.LINK_URL, {
                symbol: symbol,
                name: name,
                exchange: exchange,
                type: itemType
            });
        }
        const badgeMode = this.CONFIG.CHANGE_BADGE ? "badge-mode" : "";
        const badgeClass = this.CONFIG.CHANGE_BADGE ? "mover-change-badge" : "";
        const metrics = this.CONFIG.METRICS || [];
        let metricsHtml = "";
        for (const metric of metrics) {
            if (metric === "active.c") {
                const price = active.c;
                const formattedPrice = price !== undefined && price !== null ? this._addThousandSeparator(String(price)) : "--";
                metricsHtml += `<div class="mover-price"><span class="${wsClass}_C_1D">${formattedPrice}</span>${this.CONFIG.SHOW_CURRENCY ? `<span class="mover-currency">${currency}</span>` : ""}</div>`;
            } else if (metric === "active.ch") {
                const change = parseFloat(active.ch);
                const changeStyle = this._getValueStyle(change);
                const changeSign = !isNaN(change) && change !== 0 ? change > 0 ? "+" : "−" : "";
                const formatted = !isNaN(change) ? `<span class="sign">${changeSign}</span>${convertNumberToShortForm(Math.abs(change))}` : "--";
                metricsHtml += `<div class="mover-change ${changeStyle.class} ${badgeClass} ${wsClass}_CH_1D">${formatted}</div>`;
            } else if (metric === "active.chp") {
                const chp = parseFloat(active.chp);
                const changeStyle = this._getValueStyle(chp);
                const changeSign = !isNaN(chp) && chp !== 0 ? chp > 0 ? "+" : "−" : "";
                const formatted = !isNaN(chp) ? `<span class="sign">${changeSign}</span>${convertNumberToShortForm(Math.abs(chp), true, 2)}%` : "--";
                metricsHtml += `<div class="mover-change ${changeStyle.class} ${badgeClass} ${wsClass}_CHP_1D">${formatted}</div>`;
            } else if (metric === "active.v") {
                const vol = perf["24h_vol_cmc"] ?? active.v;
                const formatted = vol !== undefined && vol !== null ? typeof convertNumberToShortForm !== "undefined" ? convertNumberToShortForm(vol) : this._addThousandSeparator(String(vol)) : "--";
                metricsHtml += `<div class="mover-price"><span class="${wsClass}_V_1D">${formatted}</span></div>`;
            } else if (metric === "active.a") {
                const ask = active.a;
                const formatted = ask !== undefined && ask !== null ? this._addThousandSeparator(String(ask)) : "--";
                metricsHtml += `<div class="mover-price"><span class="${wsClass}_A_1D">${formatted}</span></div>`;
            } else if (metric === "active.b") {
                const bid = active.b;
                const formatted = bid !== undefined && bid !== null ? this._addThousandSeparator(String(bid)) : "--";
                metricsHtml += `<div class="mover-price"><span class="${wsClass}_B_1D">${formatted}</span></div>`;
            } else if (metric === "spread") {
                const ask = parseFloat(active.a);
                const bid = parseFloat(active.b);
                const spread = !isNaN(ask) && !isNaN(bid) ? Math.abs(ask - bid) : NaN;
                const formatted = !isNaN(spread) ? this._addThousandSeparator(String(spread.toFixed(5).replace(/\.?0+$/, ""))) : "--";
                metricsHtml += `<div class="mover-price">${formatted}</div>`;
            } else if (metric === "perf.market_cap" || metric === "perf.24h_vol_cmc") {
                const val = perf[metric.split(".")[1]];
                const formatted = val !== undefined && val !== null ? typeof convertNumberToShortForm !== "undefined" ? convertNumberToShortForm(val) : this._addThousandSeparator(String(Math.round(val))) : "--";
                metricsHtml += `<div class="mover-price">${formatted}</div>`;
            } else if (metric.startsWith("premarket.") || metric.startsWith("postmarket.")) {
                const [group, field] = metric.split(".");
                const data = item[group] || {};
                const val = data[field];
                if (field === "chp" || field === "ch") {
                    const num = parseFloat(val);
                    const style = this._getValueStyle(num);
                    const sign = !isNaN(num) && num !== 0 ? num > 0 ? "+" : "−" : "";
                    const formatted = !isNaN(num) ? `<span class="sign">${sign}</span>${field === "chp" ? convertNumberToShortForm(Math.abs(num), true, 2) + "%" : convertNumberToShortForm(Math.abs(num))}` : "--";
                    metricsHtml += `<div class="mover-change ${style.class} ${badgeClass}">${formatted}</div>`;
                } else {
                    const formatted = val !== undefined && val !== null ? field === "v" && typeof convertNumberToShortForm !== "undefined" ? convertNumberToShortForm(val) : this._addThousandSeparator(String(val)) : "--";
                    metricsHtml += `<div class="mover-price">${formatted}</div>`;
                }
            }
        }
        const wrapperTag = this.CONFIG.ENABLE_LINKS && cardUrl ? "a" : "div";
        const targetAttr = this.CONFIG.LINK_TARGET === "_blank" ? ' target="_blank" rel="noopener noreferrer"' : "";
        const hrefAttr = this.CONFIG.ENABLE_LINKS && cardUrl ? `href="${cardUrl}"${targetAttr}` : "";
        return `\n            <${wrapperTag} class="market-mover-card ${badgeMode}" ${hrefAttr} data-ticker="${ticker}">\n                <div class="mover-left">\n                    ${logoHtml ? `<div class="mover-logo-container">${logoHtml}</div>` : ""}\n                    <div class="mover-info">\n                        ${this.CONFIG.SHOW_SYMBOL ? `<div class="mover-symbol" data-tooltip-overflow="true" data-tooltip-title="${symbol}">${symbol}</div>` : ""}\n                        ${this.CONFIG.SHOW_NAME ? `<div class="mover-name" data-tooltip-overflow="true" data-tooltip-title="${name || symbol}">${name || symbol}</div>` : ""}\n                    </div>\n                </div>\n                <div class="mover-right">\n                    ${metricsHtml}\n                </div>\n            </${wrapperTag}>\n        `;
    }
    #showEmpty() {
        if (!this.gridContainer) return;
        this.gridContainer.innerHTML = `\n            <div class="market-movers-empty">\n                <svg width="200" height="200" fill="none" stroke="none">\n                    <use href="#magnifier-char"></use>\n                </svg>\n                <p>No data available</p>\n            </div>\n        `;
    }
    #showError() {
        if (!this.gridContainer) return;
        this.gridContainer.innerHTML = `\n            <div class="market-movers-error">\n                <svg width="200" height="200" fill="none" stroke="none">\n                    <use href="#magnifier-char"></use>\n                </svg>\n                <p>Failed to load data</p>\n            </div>\n        `;
    }
    #showLoading() {
        if (!this.gridContainer) return;
        let skeletonHtml = "";
        for (let i = 0; i < this.CONFIG.PER_PAGE; i++) {
            skeletonHtml += `\n                <div class="market-mover-card skeleton-card">\n                    <div class="mover-left">\n                        <div class="mover-logo-container">\n                            <span class="skeleton skeleton-circle"></span>\n                        </div>\n                        <div class="mover-info">\n                            <span class="skeleton skeleton-text" style="width: 60px; height: 14px;"></span>\n                            <span class="skeleton skeleton-text-sm" style="width: 90px; height: 12px;"></span>\n                        </div>\n                    </div>\n                    <div class="mover-right">\n                        <span class="skeleton skeleton-text" style="width: 70px; height: 14px;"></span>\n                        <span class="skeleton skeleton-text-sm" style="width: 55px; height: 12px;"></span>\n                    </div>\n                </div>\n            `;
        }
        this.gridContainer.innerHTML = skeletonHtml;
    }
    refresh() {
        this.#showLoading();
        this.#fetchData();
    }
    updateConfig(newOptions) {
        this.CONFIG = {
            ...this.CONFIG,
            ...newOptions
        };
        this.refresh();
    }
    getData() {
        return this.state.data;
    }
    destroy() {
        if (this.observer) {
            this.observer.disconnect();
            this.observer = null;
        }
        this.gridContainer = null;
        this.container = null;
    }
}

export { MarketMovers };

if (typeof window !== "undefined") {
    window.MarketMovers = MarketMovers;
}