import Logger from "../logging/Logger.js";
import APIConfig from "./APIConfig.js";
import TradingPair from "./assets/TradingPair.js";
import AccountEventListener from "./event/AccountEventListener.js";
import APIEvent from "./event/APIEvent.js";
import AssetEventListener from "./event/AssetEventListener.js";

export default class APIClient {
    /**
     * @type {APIConfig}
     */
    #apiConfig = null;

    /**
     * @type {Logger}
     */
    #logger = null;

    /**
     * @type {AccountEventListener[]}
     */
    #accountEventListeners = [];

    /**
     * @type {AssetEventListener[]}
     */
    #assetEventListeners = [];

    /**
     * @param {APIConfig} config 
     */
    constructor(config, logger) {
        this.#apiConfig = config;
        this.#logger = logger;
    }

    /**
     * @returns {APIConfig}
     */
    getApiConfig() {
        return this.#apiConfig;
    }

    /**
     * @returns {Logger}
     */
    getLogger() {
        return this.#logger;
    }

    /**
     * @param {AssetEventListener} listener 
     */
    registerAssetEventListener(listener) {
        this.#assetEventListeners.push(listener);
    }

    /**
     * @param {AccountEventListener} listener 
     */
    registerAccountEventListener(listener) {
        this.#accountEventListeners.push(listener);
    }

    /**
     * @param {APIEvent} event 
     */
    dispatchAccountEvent(event) {
        this.#accountEventListeners.forEach(handler => handler.handleAccountUpdate(event));
    }

    /**
     * @param {APIEvent} event 
     */
    dispatchAssetEvent(event) {
        this.#assetEventListeners.forEach(handler => handler.handleAssetUpdate(event));
    }

    /**
     * @param {TradingPair} tradingPair 
     */
    subscribeOrderBookUpdates(tradingPair) {
        // implement in api specific client
    }

    /**
     * @param {TradingPair} tradingPair 
     */
    subscribeKLines(tradingPair) {
        // implement in api specific client
    }

    /**
     * @param {TradingPair} tradingPair 
     */
    subscribe24hTicker(tradingPair) {
        // implement in api specific client
    }

    /**
    * @param {TradingPair} tradingPair
    */
    subscribeTrades(tradingPair) {
        // implement in api specific client
    }

    subscribeBalanceChanges() {
        // implement in api specific client
    }

    /**
     * 
     * @param {TradingPair} tradingPair 
     */
    requestOrderBook(tradingPair) {
        // implement in api specific client
    }

    requestAccountInformation() {
        // implement in api specific client
    }

    requestBalances() {
        // implement in api specific client
    }

    /**
     * @param {Transaction} transaction 
     */
    requestBuy(transaction) {
        // implement in api specific client
    }

    /**
     * @param {Transaction} transaction 
     */
    requestSell(transaction) {
        // implement in api specific client
    }

    /**
     * @param {Transaction} transaction 
     */
    requestBuyCancel(transaction) {
        // implement in api specific client
    }

    /**
     * @param {Transaction} transaction 
     */
    requestSellCancel(transaction) {
        // implement in api specific client
    }

    /**
     * @param {Transaction} transaction 
     * @param {"buy" | "sell"} type
     */
    requestTransactionUpdate(transaction, type = "buy") {
        // implement in api specific client
    }

}