// custom_values_generators.js

/**
 * Custom Values Generators Definitions
 *
 * This file contains generator functions for each block defined in
 * custom_values_blocks.js. Each generator translates a Blockly block
 * into a JSON object representing custom value operations.
 *
 * Note: This file assumes that `json_base_generator.js` has been loaded
 * before it, which initializes `Blockly.JSON` and attaches helper functions.
 */

export function defineCustomValuesGenerators() {


    /**
     * Generator for 'last_candle_value' Block
     *
     * Description:
     * Generates a JSON object to retrieve a specific part of the last candle (Open, High, Low, Close)
     * from a given source. Handles chaining with the 'NEXT' input if connected.
     */
    Blockly.JSON['last_candle_value'] = function(block) {
        // Retrieve the selected candle part from the dropdown
        const candlePart = block.getFieldValue('candle_part'); // 'open', 'high', 'low', 'close'

        // Retrieve and parse the 'source' input
        const sourceCode = Blockly.JSON.valueToCode(block, 'source', Blockly.JSON.ORDER_ATOMIC);
        let source;

        try {
            source = Blockly.JSON.safeParse(sourceCode);
            if (!source) {
                throw new Error('Source input could not be parsed.');
            }
        } catch (e) {
            console.warn(`Error parsing source input in last_candle_value block: ${e.message}`);
            source = { time_frame: '1m', exchange: '', symbol: '' }; // Default source
        }

        const json = {
            type: 'last_candle_value',
            candle_part: candlePart,
            source: source
        };

        // Handle 'NEXT' input for chaining if applicable
        // Note: According to block definitions, 'last_candle_value' does not have a 'NEXT' input
        // If in the future a 'NEXT' input is added, uncomment the following lines:
        /*
        const nextCode = Blockly.JSON.valueToCode(block, 'NEXT', Blockly.JSON.ORDER_ATOMIC);
        if (nextCode) {
            try {
                const nextJson = JSON.parse(nextCode);
                if (Array.isArray(nextJson)) {
                    json.next = [...nextJson];
                } else {
                    json.next = [nextJson];
                }
            } catch (e) {
                console.warn(`Failed to parse NEXT input in last_candle_value block: ${e.message}`);
            }
        }
        */

        return JSON.stringify(json);
    };

    /**
     * Generator for 'source' Block
     *
     * Description:
     * Generates a JSON object defining the data source based on Time Frame (TF),
     * Exchange (EXC), and Symbol (SYM). This source can be used with blocks that
     * expect a 'source' type input.
     */
    Blockly.JSON['source'] = function(block) {
        // Retrieve dropdown values
        const tf = block.getFieldValue('TF'); // Time Frame
        const exc = block.getFieldValue('EXC'); // Exchange
        const sym = block.getFieldValue('SYM'); // Symbol

        // Validate dropdown selections against available data
        const validTFs = bt_data && bt_data.intervals ? bt_data.intervals : [];
        const validExchanges = window.UI && window.UI.exchanges && window.UI.exchanges.connected_exchanges ? window.UI.exchanges.connected_exchanges : [];
        const validSymbols = bt_data && bt_data.symbols ? bt_data.symbols : [];

        if (!validTFs.includes(tf)) {
            console.warn(`Invalid Time Frame "${tf}" in source block. Defaulting to '1m'.`);
        }
        if (!validExchanges.includes(exc)) {
            console.warn(`Invalid Exchange "${exc}" in source block. Defaulting to ''.`);
        }
        if (!validSymbols.includes(sym)) {
            console.warn(`Invalid Symbol "${sym}" in source block. Defaulting to ''.`);
        }

        const json = {
            type: 'source',
            time_frame: validTFs.includes(tf) ? tf : '1m',
            exchange: validExchanges.includes(exc) ? exc : '',
            symbol: validSymbols.includes(sym) ? sym : ''
        };

        return JSON.stringify(json);
    };
}
