class Data {
    constructor() {
        // The user name
        this.user_name = bt_data.user_name;

        // The id's of the HTML elements that contain sections of the user interface.
        this.chart1_id = 'chart';
        this.chart2_id = 'chart2';
        this.chart3_id = 'chart3';
        this.chart4_id = 'chart4';
        this.chart5_id = 'chart5';  // Candlestick patterns chart

        /* Set into memory configuration data from the server. */
        // The assets being traded.
        this.trading_pair = bt_data.trading_pair;
        // The time period of the charts.
        this.interval = bt_data.timeframe || bt_data.interval || '5m';
        // All the indicators available.
        this.indicators = bt_data.indicators;

        // Initialize other properties
        this.price_history = null;
        this.indicator_data = null;
        this.last_price = null;
        this.i_updates = null;

        /* Initialize Comms with the user_name */
        this.comms = new Comms(this.user_name);
    }
    /**
     * Initializes the Data instance by setting up connections and fetching data.
     * Should be called after creating a new instance of Data.
     */
    async initialize() {
        // Register callbacks
        this.comms.registerCallback('candle_update', this.candle_update.bind(this));
        this.comms.registerCallback('candle_close', this.candle_close.bind(this));
        this.comms.registerCallback('indicator_update', this.indicator_update.bind(this));

        // Request historical price data from the server
        try {
            // Get chart view first (includes exchange info)
            const chartView = await this.comms._getChartView(this.user_name);
            this.exchange = chartView.exchange || 'binance';
            this.trading_pair = chartView.market || this.trading_pair;
            this.interval = chartView.timeframe || this.interval;

            // Open WebSocket connection for streaming candle data
            this.comms.setExchangeCon(this.interval, this.trading_pair, this.exchange);

            // Fetch price history with the chart view
            this.price_history = await this.comms.getPriceHistory(this.user_name, chartView);
            if (this.price_history && this.price_history.length > 0) {
                this.last_price = this.price_history[this.price_history.length - 1].close;
            } else {
                console.error('Received empty price history data');
            }
        } catch (error) {
            console.error('Error fetching price history:', error);
        }

        // Request indicator data from the server
        try {
            this.indicator_data = await this.comms.getIndicatorData(this.user_name);
        } catch (error) {
            console.error('Error fetching indicator data:', error);
        }
    }
    candle_update(new_candle){
        // This is called everytime a candle update comes from the local server.
        // Guard against race condition where updates arrive before chart is initialized
        if (window.UI && window.UI.charts && window.UI.charts.update_main_chart) {
            window.UI.charts.update_main_chart(new_candle);
        }
        this.last_price = new_candle.close;
    }
    registerCallback_i_updates(call_back){
        this.i_updates = call_back;
    }

    // This is called everytime an indicator update come in.
    indicator_update(data) {
        if (typeof this.i_updates === 'function') {
            this.i_updates(data);
        } else {
            console.warn('No indicator update callback registered.');
        }
    }


    async candle_close(new_candle){
        // This is called everytime a candle closes.
        // Fetch updated indicator values since indicators depend on closed candles
        try {
            const indicatorData = await this.comms.getIndicatorData(this.user_name);
            if (indicatorData) {
                this.indicator_update(indicatorData);
            }
        } catch (error) {
            console.error('Error fetching indicator data on candle close:', error);
        }
    }

    /**
     * Returns the current chart view settings.
     * Used by the strategy dialog to default to current view.
     * @returns {Object} - Chart view with exchange, market, and timeframe.
     */
    getChartView() {
        return {
            exchange: this.exchange || 'binance',
            market: this.trading_pair || 'BTC/USDT',
            timeframe: this.interval || '5m'
        };
    }
}
