/**
 * Trade Order Generators Definitions
 *
 * This file contains generator functions for each block defined in
 * trade_order_blocks.js. Each generator translates a Blockly block into a JSON
 * object representing trade order operations.
 */

export function defineTradeOrderGenerators() {

    // Ensure the base generator is initialized and 'createOperationObject' is available
    if (!Blockly.JSON || !Blockly.JSON.createOperationObject) {
        console.error("Blockly.JSON or createOperationObject not initialized. Please ensure 'json_base_generator.js' is loaded first.");
        return;
    }

    /**
     * Generator for 'trade_action' Block
     */
    Blockly.JSON['trade_action'] = function(block, argsCount = null, maxDepth = 10) {
        /**
         * Helper Function: collectTradeOptions
         * Recursively collects all connected trade_options blocks.
         *
         * @param {Blockly.Block} block - The first trade_options block.
         * @returns {Array} - Array of trade_options JSON objects.
         */
        function collectTradeOptions(block) {
            let options = [];
            while (block) {
                const optionJson = Blockly.JSON._blockToJson(block);
                if (optionJson) {
                    delete optionJson.next;
                    options.push(optionJson);
                }
                block = block.getNextBlock();
            }
            return options;
        };
       /**
         * Helper Function: validateTradeType
         * Validates the trade type and returns a default if invalid.
         *
         * @param {string} tradeType - The trade type to validate.
         * @returns {string} - Validated trade type.
         */
        function validateTradeType(tradeType) {
            const validTradeTypes = ['buy', 'sell'];
            if (!validTradeTypes.includes(tradeType)) {
                console.error(`Invalid trade type '${tradeType}' in 'trade_action' block. Defaulting to 'buy'.`);
                return 'buy';
            }
            return tradeType;
        }

        // Retrieve and validate the trade type
        const tradeType = block.getFieldValue('trade_type') || 'buy';
        const validatedTradeType = validateTradeType(tradeType);

        // Retrieve and process the trade size
        const size = Blockly.JSON.processNumericInput(block, 'size', 1); // Default size is 1

        // **Assign the processed 'size' to 'inputs.size'**
        const json = {
            type: 'trade_action',
            trade_type: validatedTradeType,
            inputs: {
                size: size
            }
        };

        // **Process 'trade_options' statement input within the generator**
        const tradeOptionsFirstBlock = block.getInputTargetBlock('trade_options');
        if (tradeOptionsFirstBlock) {
            const allTradeOptions = collectTradeOptions(tradeOptionsFirstBlock);
            if (allTradeOptions && allTradeOptions.length > 0) {
                json.trade_options = allTradeOptions;
            }
        }

        console.log(`Generated JSON for 'trade_action' block:`, json);
        return json;
    };

    /**
     * Generator for 'time_in_force' Block
     */
    Blockly.JSON['time_in_force'] = function(block) {
        // Retrieve the Time in Force value from the dropdown
        const tif = block.getFieldValue('tif') || 'gtc';
        const validTIF = ['gtc', 'fok', 'ioc'];
        const validatedTIF = validTIF.includes(tif) ? tif : 'gtc';

        if (!validTIF.includes(tif)) {
            console.error(`Invalid Time in Force '${tif}' in 'time_in_force' block. Defaulting to 'gtc'.`);
        }

        // Create operation object
        const json = {
            type: 'time_in_force',
            inputs: {
                time_in_force: validatedTIF
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'stop_loss' Block
     */
    Blockly.JSON['stop_loss'] = function(block) {
        // Retrieve and process the 'stop_loss_input' numeric input
        const stop_loss = Blockly.JSON.processNumericInput(block, 'stop_loss_input', 0);

        // Validate stop_loss
        if (stop_loss <= 0) {
            console.warn(`Invalid stop_loss value '${stop_loss}' in 'stop_loss' block. Using default value 0.`);
        }

        // Create operation object
        const json = {
            type: 'stop_loss',
            inputs: {
                stop_loss: stop_loss
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'take_profit' Block
     */
    Blockly.JSON['take_profit'] = function(block) {
        // Retrieve and process the 'take_profit_input' numeric input
        const take_profit = Blockly.JSON.processNumericInput(block, 'take_profit_input', 0);

        // Validate take_profit
        if (take_profit <= 0) {
            console.warn(`Invalid take_profit value '${take_profit}' in 'take_profit' block. Using default value 0.`);
        }

        // Create operation object
        const json = {
            type: 'take_profit',
            inputs: {
                take_profit: take_profit
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'limit' Block
     */
    Blockly.JSON['limit'] = function(block) {
        // Retrieve and process the 'limit_input' numeric input
        const limit = Blockly.JSON.processNumericInput(block, 'limit_input', 0);

        // Validate limit
        if (limit <= 0) {
            console.warn(`Invalid limit value '${limit}' in 'limit' block. Using default value 0.`);
        }

        // Create operation object
        const json = {
            type: 'limit',
            inputs: {
                limit: limit
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'trailing_stop' Block
     */
    Blockly.JSON['trailing_stop'] = function(block) {
        // Retrieve and process the 'trail_distance' numeric input
        const trail_distance = Blockly.JSON.processNumericInput(block, 'trail_distance', 0);

        // Validate trail_distance
        if (trail_distance <= 0) {
            console.warn(`Invalid trail_distance value '${trail_distance}' in 'trailing_stop' block. Using default value 0.`);
        }

        // Create operation object
        const json = {
            type: 'trailing_stop',
            inputs: {
                trail_distance: trail_distance
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'trailing_limit' Block
     */
    Blockly.JSON['trailing_limit'] = function(block) {
        // Retrieve and process the 'trail_limit_distance' numeric input
        const trail_limit_distance = Blockly.JSON.processNumericInput(block, 'trail_limit_distance', 0);

        // Validate trail_limit_distance
        if (trail_limit_distance <= 0) {
            console.warn(`Invalid trail_limit_distance value '${trail_limit_distance}' in 'trailing_limit' block. Using default value 0.`);
        }

        // Create operation object
        const json = {
            type: 'trailing_limit',
            inputs: {
                trail_limit_distance: trail_limit_distance
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'target_market' Block
     */
    Blockly.JSON['target_market'] = function(block) {
        // Retrieve the Time Frame, Exchange, and Symbol selections
        const timeFrame = block.getFieldValue('TF') || '1m'; // Default to '1m'
        const exchange = block.getFieldValue('EXC') || 'Binance'; // Default to 'Binance'
        const symbol = block.getFieldValue('SYM') || 'BTCUSDT'; // Default to 'BTCUSDT'

        // Validate fields if necessary
        // Example: Ensure timeFrame matches expected patterns
        // Skipping detailed validation for brevity

        // Create operation object
        const json = {
            type: 'target_market',
            inputs: {
                time_frame: timeFrame,
                exchange: exchange,
                symbol: symbol
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };

    /**
     * Generator for 'name_order' Block
     */
    Blockly.JSON['name_order'] = function(block) {
        // Retrieve the order name from the input field
        const orderName = (block.getFieldValue('order_name') || 'Unnamed Order').trim();

        // Validate order name
        if (!orderName) {
            console.warn("Empty 'order_name' in 'name_order' block. Using 'Unnamed Order'.");
        }

        // Create operation object
        const json = {
            type: 'name_order',
            inputs: {
                order_name: orderName || 'Unnamed Order'
            }
        };

        // No need to handle 'NEXT' input; sequencing is managed by _blockToJson

        return json;
    };
}
