"use strict";
/**
 * MYXClientService
 *
 * Stage 1 service for fetching MYX market data using the @myx-trade/sdk.
 * Handles market listing, ticker fetching, and price polling.
 *
 * Uses MyxClient SDK for API calls.
 * Trading functionality will be added in 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 _MYXClientService_instances, _MYXClientService_myxClient, _MYXClientService_isTestnet, _MYXClientService_chainId, _MYXClientService_pricePollingTimeout, _MYXClientService_pollingSymbols, _MYXClientService_pollingCallback, _MYXClientService_marketsCache, _MYXClientService_marketsCacheTimestamp, _MYXClientService_marketsCacheTtlMs, _MYXClientService_deps, _MYXClientService_getErrorContext, _MYXClientService_pollPrices, _MYXClientService_scheduleNextPoll;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MYXClientService = void 0;
const sdk_1 = require("@myx-trade/sdk");
const myxConfig_1 = require("../constants/myxConfig.cjs");
const perpsConfig_1 = require("../constants/perpsConfig.cjs");
const errorUtils_1 = require("../utils/errorUtils.cjs");
// ============================================================================
// MYXClientService
// ============================================================================
/**
 * Service for managing MYX SDK client interactions
 * Stage 1: Read-only operations (markets, prices)
 */
class MYXClientService {
    constructor(deps, config) {
        _MYXClientService_instances.add(this);
        // SDK Client
        _MYXClientService_myxClient.set(this, void 0);
        // Configuration
        _MYXClientService_isTestnet.set(this, void 0);
        _MYXClientService_chainId.set(this, void 0);
        // Price polling (sequential using setTimeout to prevent request pileup)
        _MYXClientService_pricePollingTimeout.set(this, void 0);
        _MYXClientService_pollingSymbols.set(this, []);
        _MYXClientService_pollingCallback.set(this, void 0);
        // Caches
        _MYXClientService_marketsCache.set(this, []);
        _MYXClientService_marketsCacheTimestamp.set(this, 0);
        _MYXClientService_marketsCacheTtlMs.set(this, 5 * 60 * 1000); // 5 minutes
        // Platform dependencies
        _MYXClientService_deps.set(this, void 0);
        __classPrivateFieldSet(this, _MYXClientService_deps, deps, "f");
        __classPrivateFieldSet(this, _MYXClientService_isTestnet, config.isTestnet, "f");
        __classPrivateFieldSet(this, _MYXClientService_chainId, (0, myxConfig_1.getMYXChainId)(__classPrivateFieldGet(this, _MYXClientService_isTestnet, "f") ? 'testnet' : 'mainnet'), "f");
        // Initialize MyxClient
        __classPrivateFieldSet(this, _MYXClientService_myxClient, new sdk_1.MyxClient({
            chainId: __classPrivateFieldGet(this, _MYXClientService_chainId, "f"),
            brokerAddress: '0x0000000000000000000000000000000000000000', // Not needed for read-only
            isTestnet: __classPrivateFieldGet(this, _MYXClientService_isTestnet, "f"),
            isBetaMode: __classPrivateFieldGet(this, _MYXClientService_isTestnet, "f"), // Use beta API for testnet
        }), "f");
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Initialized with SDK', {
            isTestnet: __classPrivateFieldGet(this, _MYXClientService_isTestnet, "f"),
            chainId: __classPrivateFieldGet(this, _MYXClientService_chainId, "f"),
        });
    }
    // ============================================================================
    // Market Operations
    // ============================================================================
    /**
     * Get all available markets/pools
     * Uses SDK markets.getPoolSymbolAll()
     *
     * @returns The array of available MYX pool symbols.
     */
    async getMarkets() {
        // Return cache if valid
        const now = Date.now();
        if (__classPrivateFieldGet(this, _MYXClientService_marketsCache, "f").length > 0 &&
            now - __classPrivateFieldGet(this, _MYXClientService_marketsCacheTimestamp, "f") < __classPrivateFieldGet(this, _MYXClientService_marketsCacheTtlMs, "f")) {
            return __classPrivateFieldGet(this, _MYXClientService_marketsCache, "f");
        }
        try {
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Fetching markets via SDK');
            const pools = await __classPrivateFieldGet(this, _MYXClientService_myxClient, "f").markets.getPoolSymbolAll();
            // Update cache
            __classPrivateFieldSet(this, _MYXClientService_marketsCache, pools || [], "f");
            __classPrivateFieldSet(this, _MYXClientService_marketsCacheTimestamp, Date.now(), "f");
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Markets fetched', {
                count: __classPrivateFieldGet(this, _MYXClientService_marketsCache, "f").length,
            });
            return __classPrivateFieldGet(this, _MYXClientService_marketsCache, "f");
        }
        catch (caughtError) {
            const wrappedError = (0, errorUtils_1.ensureError)(caughtError, 'MYXClientService.getMarkets');
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_getErrorContext).call(this, 'getMarkets'));
            // Return stale cache if available
            if (__classPrivateFieldGet(this, _MYXClientService_marketsCache, "f").length > 0) {
                __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Returning stale cache after error');
                return __classPrivateFieldGet(this, _MYXClientService_marketsCache, "f");
            }
            throw wrappedError;
        }
    }
    /**
     * Get tickers for specific symbols/pools
     * Uses SDK markets.getTickerList()
     *
     * @param poolIds - The array of pool identifiers to fetch tickers for.
     * @returns The array of ticker data for the specified pools.
     */
    async getTickers(poolIds) {
        if (poolIds.length === 0) {
            return [];
        }
        try {
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Fetching tickers via SDK', {
                poolIds: poolIds.length,
            });
            const tickers = await __classPrivateFieldGet(this, _MYXClientService_myxClient, "f").markets.getTickerList({
                chainId: __classPrivateFieldGet(this, _MYXClientService_chainId, "f"),
                poolIds,
            });
            return tickers || [];
        }
        catch (caughtError) {
            const wrappedError = (0, errorUtils_1.ensureError)(caughtError, 'MYXClientService.getTickers');
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_getErrorContext).call(this, 'getTickers', { poolIds }));
            throw wrappedError;
        }
    }
    /**
     * Get all tickers (for all available markets)
     *
     * @returns The array of ticker data for all available markets.
     */
    async getAllTickers() {
        try {
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Fetching all tickers via SDK');
            // Get all pools first, then fetch tickers for them
            const pools = await this.getMarkets();
            const poolIds = pools.map((pool) => pool.poolId);
            if (poolIds.length === 0) {
                return [];
            }
            return this.getTickers(poolIds);
        }
        catch (caughtError) {
            const wrappedError = (0, errorUtils_1.ensureError)(caughtError, 'MYXClientService.getAllTickers');
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").logger.error(wrappedError, __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_getErrorContext).call(this, 'getAllTickers'));
            throw wrappedError;
        }
    }
    // ============================================================================
    // Price Polling
    // ============================================================================
    /**
     * Start polling for price updates.
     * Uses sequential setTimeout to prevent request pileup — the next poll
     * is only scheduled after the current one completes (or fails).
     *
     * @param poolIds - The array of pool identifiers to poll prices for.
     * @param callback - The callback invoked with updated ticker data on each poll.
     */
    startPricePolling(poolIds, callback) {
        // Stop existing polling
        this.stopPricePolling();
        __classPrivateFieldSet(this, _MYXClientService_pollingSymbols, poolIds, "f");
        __classPrivateFieldSet(this, _MYXClientService_pollingCallback, callback, "f");
        // Fetch immediately, then schedule subsequent polls
        __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_pollPrices).call(this).catch(() => {
            // Error handling is done inside #pollPrices
        });
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Started price polling', {
            symbols: poolIds.length,
            intervalMs: myxConfig_1.MYX_PRICE_POLLING_INTERVAL_MS,
        });
    }
    /**
     * Stop price polling
     */
    stopPricePolling() {
        if (__classPrivateFieldGet(this, _MYXClientService_pricePollingTimeout, "f")) {
            clearTimeout(__classPrivateFieldGet(this, _MYXClientService_pricePollingTimeout, "f"));
            __classPrivateFieldSet(this, _MYXClientService_pricePollingTimeout, undefined, "f");
        }
        __classPrivateFieldSet(this, _MYXClientService_pollingSymbols, [], "f");
        __classPrivateFieldSet(this, _MYXClientService_pollingCallback, undefined, "f");
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Stopped price polling');
    }
    // ============================================================================
    // Health Check
    // ============================================================================
    /**
     * Health check — attempts a lightweight REST call (getTickerList with empty poolIds)
     * to verify the MYX API is reachable.
     *
     * @param timeoutMs - The timeout in milliseconds for the ping request.
     */
    async ping(timeoutMs = 5000) {
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Ping - checking REST health');
        let timeoutId;
        const timeoutPromise = new Promise((_resolve, reject) => {
            timeoutId = setTimeout(() => reject(new Error('MYX ping timeout')), timeoutMs);
        });
        try {
            await Promise.race([
                __classPrivateFieldGet(this, _MYXClientService_myxClient, "f").markets.getTickerList({
                    chainId: __classPrivateFieldGet(this, _MYXClientService_chainId, "f"),
                    poolIds: [],
                }),
                timeoutPromise,
            ]);
        }
        catch (caughtError) {
            const wrappedError = (0, errorUtils_1.ensureError)(caughtError, 'MYXClientService.ping');
            __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Ping failed', {
                error: wrappedError.message,
            });
            throw wrappedError;
        }
        finally {
            clearTimeout(timeoutId);
        }
    }
    // ============================================================================
    // Lifecycle
    // ============================================================================
    /**
     * Disconnect and cleanup
     */
    disconnect() {
        this.stopPricePolling();
        __classPrivateFieldSet(this, _MYXClientService_marketsCache, [], "f");
        __classPrivateFieldSet(this, _MYXClientService_marketsCacheTimestamp, 0, "f");
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Disconnected');
    }
    /**
     * Get current network mode
     *
     * @returns True if the service is in testnet mode.
     */
    getIsTestnet() {
        return __classPrivateFieldGet(this, _MYXClientService_isTestnet, "f");
    }
}
exports.MYXClientService = MYXClientService;
_MYXClientService_myxClient = new WeakMap(), _MYXClientService_isTestnet = new WeakMap(), _MYXClientService_chainId = new WeakMap(), _MYXClientService_pricePollingTimeout = new WeakMap(), _MYXClientService_pollingSymbols = new WeakMap(), _MYXClientService_pollingCallback = new WeakMap(), _MYXClientService_marketsCache = new WeakMap(), _MYXClientService_marketsCacheTimestamp = new WeakMap(), _MYXClientService_marketsCacheTtlMs = new WeakMap(), _MYXClientService_deps = new WeakMap(), _MYXClientService_instances = new WeakSet(), _MYXClientService_getErrorContext = function _MYXClientService_getErrorContext(method, extra) {
    return {
        tags: {
            feature: perpsConfig_1.PERPS_CONSTANTS.FeatureName,
            service: 'MYXClientService',
            network: __classPrivateFieldGet(this, _MYXClientService_isTestnet, "f") ? 'testnet' : 'mainnet',
        },
        context: {
            name: `MYXClientService.${method}`,
            data: {
                chainId: __classPrivateFieldGet(this, _MYXClientService_chainId, "f"),
                ...extra,
            },
        },
    };
}, _MYXClientService_pollPrices = 
/**
 * Execute a single price poll, then schedule the next one.
 * Sequential pattern ensures no request pileup if polls take longer than the interval.
 */
async function _MYXClientService_pollPrices() {
    if (!__classPrivateFieldGet(this, _MYXClientService_pollingCallback, "f") || __classPrivateFieldGet(this, _MYXClientService_pollingSymbols, "f").length === 0) {
        return;
    }
    try {
        const tickers = await this.getTickers(__classPrivateFieldGet(this, _MYXClientService_pollingSymbols, "f"));
        // Re-check: polling may have been stopped during the await
        // (TS narrows after early return but can't track mutations across await)
        const callback = __classPrivateFieldGet(this, _MYXClientService_pollingCallback, "f");
        if (callback) {
            callback(tickers);
        }
    }
    catch (caughtError) {
        const wrappedError = (0, errorUtils_1.ensureError)(caughtError, 'MYXClientService.pollPrices');
        __classPrivateFieldGet(this, _MYXClientService_deps, "f").debugLogger.log('[MYXClientService] Price poll failed', {
            error: wrappedError.message,
        });
        // Don't propagate error - polling continues
    }
    finally {
        __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_scheduleNextPoll).call(this);
    }
}, _MYXClientService_scheduleNextPoll = function _MYXClientService_scheduleNextPoll() {
    // Only schedule if polling is still active
    if (!__classPrivateFieldGet(this, _MYXClientService_pollingCallback, "f") || __classPrivateFieldGet(this, _MYXClientService_pollingSymbols, "f").length === 0) {
        return;
    }
    __classPrivateFieldSet(this, _MYXClientService_pricePollingTimeout, setTimeout(() => {
        __classPrivateFieldGet(this, _MYXClientService_instances, "m", _MYXClientService_pollPrices).call(this).catch(() => {
            // Error handling is done inside #pollPrices
        });
    }, myxConfig_1.MYX_PRICE_POLLING_INTERVAL_MS), "f");
};
//# sourceMappingURL=MYXClientService.cjs.map