/**
 * MYXProvider
 *
 * Stage 1 provider implementation for MYX protocol.
 * Implements the PerpsProvider interface with read-only operations.
 * Trading functionality will be added in Stage 3.
 *
 * Key differences from HyperLiquid:
 * - Uses USDT collateral on BNB chain (vs USDC on Arbitrum)
 * - Multi-Pool Model: multiple pools can exist per symbol
 * - Uses REST polling for prices (WebSocket deferred to Stage 3)
 */
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _MYXProvider_instances, _MYXProvider_deps, _MYXProvider_clientService, _MYXProvider_isTestnet, _MYXProvider_poolsCache, _MYXProvider_poolSymbolMap, _MYXProvider_tickersCache, _MYXProvider_getErrorContext, _MYXProvider_getAdaptedPrice;
import { PERPS_CONSTANTS } from "../constants/perpsConfig.mjs";
import { MYXClientService } from "../services/MYXClientService.mjs";
import { WebSocketConnectionState } from "../types/index.mjs";
import { ensureError } from "../utils/errorUtils.mjs";
import { adaptMarketFromMYX, adaptMarketDataFromMYX, adaptPriceFromMYX, filterMYXExclusiveMarkets, buildPoolSymbolMap } from "../utils/myxAdapter.mjs";
// ============================================================================
// Constants
// ============================================================================
const MYX_NOT_SUPPORTED_ERROR = 'MYX trading not yet supported';
const MYX_BLOCK_EXPLORER_URL = 'https://bscscan.com';
const MYX_TESTNET_EXPLORER_URL = 'https://testnet.bscscan.com';
// ============================================================================
// MYXProvider
// ============================================================================
/**
 * MYX provider implementation
 *
 * Stage 1: Read-only operations (markets, prices)
 * Trading operations return errors until Stage 3.
 */
export class MYXProvider {
    constructor(options) {
        _MYXProvider_instances.add(this);
        this.protocolId = 'myx';
        // Platform dependencies
        _MYXProvider_deps.set(this, void 0);
        // Client service
        _MYXProvider_clientService.set(this, void 0);
        // Configuration
        _MYXProvider_isTestnet.set(this, void 0);
        // Cache for pools (freshness delegated to MYXClientService)
        _MYXProvider_poolsCache.set(this, []);
        _MYXProvider_poolSymbolMap.set(this, new Map());
        // Ticker cache for price data
        _MYXProvider_tickersCache.set(this, new Map());
        __classPrivateFieldSet(this, _MYXProvider_deps, options.platformDependencies, "f");
        __classPrivateFieldSet(this, _MYXProvider_isTestnet, options.isTestnet ?? true, "f"); // Force testnet in Stage 1
        // Initialize client service
        __classPrivateFieldSet(this, _MYXProvider_clientService, new MYXClientService(__classPrivateFieldGet(this, _MYXProvider_deps, "f"), {
            isTestnet: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f"),
        }), "f");
        __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Constructor complete', {
            protocolId: this.protocolId,
            isTestnet: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f"),
        });
    }
    // ============================================================================
    // Initialization & Lifecycle
    // ============================================================================
    async initialize() {
        try {
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Initializing...');
            // Fetch initial markets
            const pools = await __classPrivateFieldGet(this, _MYXProvider_clientService, "f").getMarkets();
            // Filter to MYX-exclusive markets
            __classPrivateFieldSet(this, _MYXProvider_poolsCache, filterMYXExclusiveMarkets(pools), "f");
            __classPrivateFieldSet(this, _MYXProvider_poolSymbolMap, buildPoolSymbolMap(__classPrivateFieldGet(this, _MYXProvider_poolsCache, "f")), "f");
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Initialized successfully', {
                totalPools: pools.length,
                exclusivePools: __classPrivateFieldGet(this, _MYXProvider_poolsCache, "f").length,
            });
            return { success: true };
        }
        catch (caughtError) {
            const wrappedError = ensureError(caughtError, 'MYXProvider.initialize');
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXProvider_instances, "m", _MYXProvider_getErrorContext).call(this, 'initialize'));
            return { success: false, error: wrappedError.message };
        }
    }
    async disconnect() {
        try {
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Disconnecting...');
            __classPrivateFieldGet(this, _MYXProvider_clientService, "f").disconnect();
            __classPrivateFieldSet(this, _MYXProvider_poolsCache, [], "f");
            __classPrivateFieldGet(this, _MYXProvider_poolSymbolMap, "f").clear();
            __classPrivateFieldGet(this, _MYXProvider_tickersCache, "f").clear();
            return { success: true };
        }
        catch (caughtError) {
            const wrappedError = ensureError(caughtError, 'MYXProvider.disconnect');
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXProvider_instances, "m", _MYXProvider_getErrorContext).call(this, 'disconnect'));
            return { success: false, error: wrappedError.message };
        }
    }
    async ping(timeoutMs) {
        await __classPrivateFieldGet(this, _MYXProvider_clientService, "f").ping(timeoutMs);
    }
    async toggleTestnet() {
        // Stage 1: Testnet only
        return {
            success: false,
            isTestnet: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f"),
            error: 'MYX mainnet not yet available',
        };
    }
    async isReadyToTrade() {
        // Stage 1: Trading not supported
        return {
            ready: false,
            error: 'MYX trading not yet supported',
            walletConnected: false,
            networkSupported: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f"),
        };
    }
    // ============================================================================
    // Market Data Operations (Stage 1 - Fully Implemented)
    // ============================================================================
    // TODO: Align error handling - read operations should return empty defaults
    // instead of throwing, matching HyperLiquid pattern
    async getMarkets(_params) {
        try {
            // Delegate cache freshness to MYXClientService
            const pools = await __classPrivateFieldGet(this, _MYXProvider_clientService, "f").getMarkets();
            __classPrivateFieldSet(this, _MYXProvider_poolsCache, filterMYXExclusiveMarkets(pools), "f");
            __classPrivateFieldSet(this, _MYXProvider_poolSymbolMap, buildPoolSymbolMap(__classPrivateFieldGet(this, _MYXProvider_poolsCache, "f")), "f");
            return __classPrivateFieldGet(this, _MYXProvider_poolsCache, "f").map((pool) => adaptMarketFromMYX(pool));
        }
        catch (caughtError) {
            const wrappedError = ensureError(caughtError, 'MYXProvider.getMarkets');
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXProvider_instances, "m", _MYXProvider_getErrorContext).call(this, 'getMarkets'));
            throw wrappedError;
        }
    }
    async getMarketDataWithPrices() {
        try {
            // Ensure we have markets
            if (__classPrivateFieldGet(this, _MYXProvider_poolsCache, "f").length === 0) {
                await this.getMarkets();
            }
            // Fetch tickers for all pools
            const poolIds = __classPrivateFieldGet(this, _MYXProvider_poolsCache, "f").map((pool) => pool.poolId);
            const tickers = await __classPrivateFieldGet(this, _MYXProvider_clientService, "f").getTickers(poolIds);
            // Build ticker map
            const tickerMap = new Map();
            for (const ticker of tickers) {
                tickerMap.set(ticker.poolId, ticker);
                __classPrivateFieldGet(this, _MYXProvider_tickersCache, "f").set(ticker.poolId, ticker);
            }
            // Transform to PerpsMarketData
            return __classPrivateFieldGet(this, _MYXProvider_poolsCache, "f").map((pool) => {
                const ticker = tickerMap.get(pool.poolId);
                return adaptMarketDataFromMYX(pool, ticker, __classPrivateFieldGet(this, _MYXProvider_deps, "f").marketDataFormatters);
            });
        }
        catch (caughtError) {
            const wrappedError = ensureError(caughtError, 'MYXProvider.getMarketDataWithPrices');
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXProvider_instances, "m", _MYXProvider_getErrorContext).call(this, 'getMarketDataWithPrices'));
            throw wrappedError;
        }
    }
    // ============================================================================
    // Price Subscriptions (Stage 1 - REST Polling)
    // ============================================================================
    subscribeToPrices(params) {
        const { symbols, callback, includeOrderBook } = params;
        __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Setting up price subscription', {
            symbols: symbols.length,
            includeOrderBook,
        });
        // Map symbols to pool IDs
        const poolIds = [];
        for (const pool of __classPrivateFieldGet(this, _MYXProvider_poolsCache, "f")) {
            const symbol = pool.baseSymbol || pool.poolId;
            if (symbols.includes(symbol)) {
                poolIds.push(pool.poolId);
            }
        }
        if (poolIds.length === 0) {
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] subscribeToPrices: No pool IDs found. Ensure initialize() has been called.', { symbols });
            setTimeout(() => params.callback([]), 0);
            return () => {
                /* noop */
            };
        }
        // Start price polling
        __classPrivateFieldGet(this, _MYXProvider_clientService, "f").startPricePolling(poolIds, (tickers) => {
            // Convert tickers to PriceUpdate format
            const updates = tickers.map((ticker) => {
                const symbol = __classPrivateFieldGet(this, _MYXProvider_poolSymbolMap, "f").get(ticker.poolId) ?? ticker.poolId;
                const { price, change24h } = __classPrivateFieldGet(this, _MYXProvider_instances, "m", _MYXProvider_getAdaptedPrice).call(this, ticker);
                return {
                    symbol,
                    price,
                    timestamp: Date.now(),
                    percentChange24h: change24h.toFixed(2),
                    providerId: 'myx',
                };
            });
            callback(updates);
        });
        // Return unsubscribe function
        return () => {
            __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] Unsubscribing from prices');
            __classPrivateFieldGet(this, _MYXProvider_clientService, "f").stopPricePolling();
        };
    }
    // ============================================================================
    // Asset Routes (Stage 1 - Stubbed)
    // ============================================================================
    getDepositRoutes(_params) {
        // Stage 1: No deposit support
        return [];
    }
    getWithdrawalRoutes(_params) {
        // Stage 1: No withdrawal support
        return [];
    }
    // ============================================================================
    // Trading Operations (Stage 1 - All Stubbed)
    // ============================================================================
    async placeOrder(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async editOrder(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async cancelOrder(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async cancelOrders(_params) {
        return {
            success: false,
            successCount: 0,
            failureCount: 0,
            results: [],
        };
    }
    async closePosition(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async closePositions(_params) {
        return {
            success: false,
            successCount: 0,
            failureCount: 0,
            results: [],
        };
    }
    async updatePositionTPSL(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async updateMargin(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    async withdraw(_params) {
        return {
            success: false,
            error: MYX_NOT_SUPPORTED_ERROR,
        };
    }
    // ============================================================================
    // Account Operations (Stage 1 - Empty Returns)
    // ============================================================================
    async getPositions(_params) {
        // Stage 1: No position tracking
        return [];
    }
    async getAccountState(_params) {
        // Stage 1: Empty account state
        return {
            availableBalance: '0',
            totalBalance: '0',
            marginUsed: '0',
            unrealizedPnl: '0',
            returnOnEquity: '0',
        };
    }
    async getOrders(_params) {
        // Stage 1: No order tracking
        return [];
    }
    async getOpenOrders(_params) {
        // Stage 1: No order tracking
        return [];
    }
    async getOrderFills(_params) {
        // Stage 1: No fill tracking
        return [];
    }
    async getOrFetchFills(_params) {
        // Stage 1: No fill tracking
        return [];
    }
    async getFunding(_params) {
        // Stage 1: No funding tracking
        return [];
    }
    async getHistoricalPortfolio(_params) {
        return {
            accountValue1dAgo: '0',
            timestamp: Date.now(),
        };
    }
    async getUserNonFundingLedgerUpdates(_params) {
        return [];
    }
    async getUserHistory(_params) {
        return [];
    }
    // ============================================================================
    // Validation Operations (Stage 1 - All Invalid)
    // ============================================================================
    async validateDeposit(_params) {
        return { isValid: false, error: MYX_NOT_SUPPORTED_ERROR };
    }
    async validateOrder(_params) {
        return { isValid: false, error: MYX_NOT_SUPPORTED_ERROR };
    }
    async validateClosePosition(_params) {
        return { isValid: false, error: MYX_NOT_SUPPORTED_ERROR };
    }
    async validateWithdrawal(_params) {
        return { isValid: false, error: MYX_NOT_SUPPORTED_ERROR };
    }
    // ============================================================================
    // Protocol Calculations (Stage 1 - Default Values)
    // ============================================================================
    async calculateLiquidationPrice(_params) {
        return '0';
    }
    async calculateMaintenanceMargin(_params) {
        return 0;
    }
    async getMaxLeverage(_asset) {
        return 100; // MYX default max leverage
    }
    async calculateFees(_params) {
        // MYX fee structure (placeholder values)
        return {
            feeRate: 0.0005, // 0.05% total fee rate
            protocolFeeRate: 0.0005, // Protocol taker fee
        };
    }
    // ============================================================================
    // Subscriptions (Stage 1 - No-op)
    // ============================================================================
    subscribeToPositions(params) {
        // Stage 1: No position tracking - immediately call back with empty array
        // to signal loading is complete (no data to show)
        setTimeout(() => params.callback([]), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToOrderFills(params) {
        // Stage 1: No fill tracking - immediately call back with empty array
        setTimeout(() => params.callback([]), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToOrders(params) {
        // Stage 1: No order tracking - immediately call back with empty array
        setTimeout(() => params.callback([]), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToAccount(params) {
        // Stage 1: Empty account state - immediately call back
        setTimeout(() => params.callback({
            availableBalance: '0',
            totalBalance: '0',
            marginUsed: '0',
            unrealizedPnl: '0',
            returnOnEquity: '0',
        }), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToOICaps(params) {
        // Stage 1: No OI caps - immediately call back with empty array
        // (matches HyperLiquid pattern which calls callback with cached data)
        setTimeout(() => params.callback([]), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToCandles(params) {
        // Stage 1: No candle data - immediately call back with empty candles
        // (matches HyperLiquid pattern which calls callback after initial fetch)
        setTimeout(() => params.callback({
            symbol: params.symbol,
            interval: params.interval,
            candles: [],
        }), 0);
        return () => {
            /* noop */
        };
    }
    subscribeToOrderBook(params) {
        // Stage 1: No order book - immediately call back with empty data
        setTimeout(() => params.callback({
            bids: [],
            asks: [],
            spread: '0',
            spreadPercentage: '0',
            midPrice: '0',
            lastUpdated: Date.now(),
            maxTotal: '0',
        }), 0);
        return () => {
            /* noop */
        };
    }
    setLiveDataConfig(_config) {
        // Stage 1: No-op
    }
    // ============================================================================
    // Connection State (Stage 1 - REST Only)
    // ============================================================================
    getWebSocketConnectionState() {
        // Stage 1: No WebSocket, report as connected (REST is always available)
        return WebSocketConnectionState.Connected;
    }
    subscribeToConnectionState(_listener) {
        // Stage 1: No WebSocket, no connection state changes
        return () => {
            /* noop */
        };
    }
    async reconnect() {
        // Stage 1: No WebSocket to reconnect
        __classPrivateFieldGet(this, _MYXProvider_deps, "f").debugLogger.log('[MYXProvider] reconnect() is no-op in Stage 1');
    }
    // ============================================================================
    // Block Explorer
    // ============================================================================
    getBlockExplorerUrl(address) {
        const baseUrl = __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f")
            ? MYX_TESTNET_EXPLORER_URL
            : MYX_BLOCK_EXPLORER_URL;
        return address ? `${baseUrl}/address/${address}` : baseUrl;
    }
    // ============================================================================
    // Fee Discount (Stage 1 - No-op)
    // ============================================================================
    setUserFeeDiscount(_discountBips) {
        // Stage 1: No fee discount support
    }
    // ============================================================================
    // HIP-3 Operations (N/A for MYX)
    // ============================================================================
    async getAvailableDexs() {
        // MYX doesn't have HIP-3 equivalent
        return [];
    }
}
_MYXProvider_deps = new WeakMap(), _MYXProvider_clientService = new WeakMap(), _MYXProvider_isTestnet = new WeakMap(), _MYXProvider_poolsCache = new WeakMap(), _MYXProvider_poolSymbolMap = new WeakMap(), _MYXProvider_tickersCache = new WeakMap(), _MYXProvider_instances = new WeakSet(), _MYXProvider_getErrorContext = function _MYXProvider_getErrorContext(method, extra) {
    return {
        tags: {
            feature: PERPS_CONSTANTS.FeatureName,
            provider: 'MYXProvider',
            network: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f") ? 'testnet' : 'mainnet',
        },
        context: {
            name: `MYXProvider.${method}`,
            data: {
                isTestnet: __classPrivateFieldGet(this, _MYXProvider_isTestnet, "f"),
                ...extra,
            },
        },
    };
}, _MYXProvider_getAdaptedPrice = function _MYXProvider_getAdaptedPrice(ticker) {
    return adaptPriceFromMYX(ticker);
};
//# sourceMappingURL=MYXProvider.mjs.map