import { BaseRestClient } from "./base";
import { BinanceRestClient, BinanceFuturesRestClient } from "./binance/rest";
import type { FetchKlinesParams, Kline } from "../types";

/** 交易所 ID 到 RestClient 构造器的注册表 */
const registry: Record<string, () => BaseRestClient> = {
    binance: () => new BinanceRestClient(),
    binance_futures: () => new BinanceFuturesRestClient(),
};

/**
 * 创建交易所 REST 客户端。
 *
 * 根据交易所 ID 返回对应的 RestClient 实例，
 * 外部无需感知具体子类。
 *
 * @param exchangeId - 交易所标识（如 "binance"）
 * @returns 对应交易所的 RestClient 实例
 * @throws 如果 exchangeId 未注册
 */
export function createRestClient(exchangeId: string): BaseRestClient {
    const factory = registry[exchangeId];
    if (!factory) {
        const supported = Object.keys(registry).join(", ");
        throw new Error(
            `[exchanges] 不支持的交易所: "${exchangeId}"，当前支持: ${supported}`,
        );
    }
    return factory();
}

/**
 * 拉取历史 K 线（静态便捷方法）。
 *
 * 根据 exchange + type 自动路由到正确的交易所客户端，
 * 调用方无需手动创建 client 或选择 spot/futures 子类。
 *
 * 路由规则：
 *   - type = "spot"  → exchange（如 "binance"）
 *   - type = "um"/"cm" → `${exchange}_futures`（如 "binance_futures"）
 *
 * @param params - fetchKlines 统一参数对象
 * @returns 标准化 K 线数组，按时间升序
 *
 * @example
 *   const klines = await fetchKlines({
 *     exchange: 'binance',
 *     type: 'um',
 *     symbol: 'BTCUSDT',
 *     startTime: 1700000000000,
 *     limit: 500,
 *   });
 */
export async function fetchKlines(params: FetchKlinesParams): Promise<Kline[]> {
    const exchangeId =
        params.type === "spot"
            ? params.exchange
            : `${params.exchange}_futures`;
    const client = createRestClient(exchangeId);
    return client.fetchKlines(params);
}

export { BaseRestClient } from "./base";
export { BinanceRestClient, BinanceFuturesRestClient } from "./binance/rest";
export { KLINE_INTERVAL_MS } from "./constants";
