/**
 * Logical Generators Definitions
 *
 * This file contains generator functions for each block defined in
 * logical_blocks.js. Each generator translates a Blockly block into a JSON
 * object representing logical operations such as comparisons, logical AND/OR,
 * boolean condition checks, and flag evaluations.
 */

export function defineLogicalGenerators() {

    // 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;
    }

    /**
     * Helper Function: processTwoValueInput
     * Processes two value inputs ('LEFT' and 'RIGHT') and returns their values.
     *
     * @param {Blockly.Block} block - The block containing the inputs.
     * @returns {Object} - An object containing 'left' and 'right' values.
     */
    function processTwoValueInput(block) {
        const leftBlock = block.getInputTargetBlock('LEFT');
        const rightBlock = block.getInputTargetBlock('RIGHT');

        let left = null;
        let right = null;

        if (leftBlock) {
            const leftJson = Blockly.JSON.blockToCode(leftBlock);
            left = typeof leftJson !== 'undefined' ? leftJson : null;
        } else {
            console.warn(`No block connected to 'LEFT' input of '${block.type}' block. Using default value.`);
            left = null; // Assign a default value if necessary
        }

        if (rightBlock) {
            const rightJson = Blockly.JSON.blockToCode(rightBlock);
            right = typeof rightJson !== 'undefined' ? rightJson : null;
        } else {
            console.warn(`No block connected to 'RIGHT' input of '${block.type}' block. Using default value.`);
            right = null; // Assign a default value if necessary
        }

        return { left, right };
    }

    /**
     * Generator for 'comparison' Block
     *
     * Generates a JSON object representing a comparison operation between two values
     * using operators like '>', '<', '=='. Outputs a Boolean value based on the comparison result.
     */
    Blockly.JSON['comparison'] = function(block) {
        /**
         * Helper Function: processTwoValueInput
         * Processes 'LEFT' and 'RIGHT' inputs and returns their JSON representations.
         *
         * @param {Blockly.Block} block - The block containing the 'LEFT' and 'RIGHT' inputs.
         * @returns {Object} - An object with 'LEFT' and 'RIGHT' properties.
         */
        function processTwoValueInput(block) {
            const leftBlock = block.getInputTargetBlock('LEFT');
            const rightBlock = block.getInputTargetBlock('RIGHT');

            let left = null;
            let right = null;

            if (leftBlock) {
                left = Blockly.JSON.blockToCode(leftBlock);
                if (typeof left !== 'object' || left === null) {
                    console.error(`Invalid 'LEFT' input in 'comparison' block. Expected an object.`);
                    left = 0;
                }
            } else {
                console.warn(`No block connected to 'LEFT' input of 'comparison' block. Using default value 0.`);
                left = 0; // Assign a default value if necessary
            }

            if (rightBlock) {
                right = Blockly.JSON.blockToCode(rightBlock);
                if (typeof right !== 'object' || right === null) {
                    console.error(`Invalid 'RIGHT' input in 'comparison' block. Expected an object.`);
                    right = 0;
                }
            } else {
                console.warn(`No block connected to 'RIGHT' input of 'comparison' block. Using default value 0.`);
                right = 0; // Assign a default value if necessary
            }

            return { LEFT: left, RIGHT: right };
        }

        const { LEFT, RIGHT } = processTwoValueInput(block);

        // Retrieve the selected operator
        const operator = block.getFieldValue('OPERATOR'); // Must match the block definition
        const validOperators = ['>', '<', '==', '!=', '>=', '<='];
        if (!validOperators.includes(operator)) {
            console.error(`Invalid operator '${operator}' in 'comparison' block. Defaulting to '=='`);
        }
        const validatedOperator = validOperators.includes(operator) ? operator : '==';

        // Create operation object with 'inputs'
        const operationObject = {
            type: 'comparison',
            operator: validatedOperator,
            inputs: {
                LEFT: LEFT !== null ? LEFT : { type: 'dynamic_value', values: [0] },
                RIGHT: RIGHT !== null ? RIGHT : { type: 'dynamic_value', values: [0] }
            },
            skipAdditionalParsing: true

        };

        return operationObject;
    };


    /**
     * Generator for 'logical_and' Block
     *
     * Generates a JSON object representing a logical AND operation between two conditions.
     */
    Blockly.JSON['logical_and'] = function(block) {
        // Get the connected blocks
        const leftBlock = block.getInputTargetBlock('LEFT');
        const rightBlock = block.getInputTargetBlock('RIGHT');

        let leftValue = null;
        let rightValue = null;

        // Process the left input
        if (leftBlock) {
            const leftGenerator = Blockly.JSON[leftBlock.type];
            if (typeof leftGenerator === 'function') {
                leftValue = leftGenerator(leftBlock);
            } else {
                console.warn(`No generator found for block type "${leftBlock.type}". Defaulting left input to false.`);
                leftValue = false;
            }
        } else {
            console.warn("No block connected to 'LEFT' input of 'logical_and' block. Defaulting to false.");
            leftValue = false;
        }

        // Process the right input
        if (rightBlock) {
            const rightGenerator = Blockly.JSON[rightBlock.type];
            if (typeof rightGenerator === 'function') {
                rightValue = rightGenerator(rightBlock);
            } else {
                console.warn(`No generator found for block type "${rightBlock.type}". Defaulting right input to false.`);
                rightValue = false;
            }
        } else {
            console.warn("No block connected to 'RIGHT' input of 'logical_and' block. Defaulting to false.");
            rightValue = false;
        }

        // Create the logical_and operation object
        const json = {
            type: 'logical_and',
            inputs: {
                left: leftValue,
                right: rightValue
            }
        };

        return json;
    };


    /**
     * Generator for 'logical_or' Block
     *
     * Generates a JSON object representing a logical OR operation between two conditions.
     */
    Blockly.JSON['logical_or'] = function(block) {
        // Get the connected blocks
        const leftBlock = block.getInputTargetBlock('LEFT');
        const rightBlock = block.getInputTargetBlock('RIGHT');

        let leftValue = null;
        let rightValue = null;

        // Process the left input
        if (leftBlock) {
            const leftGenerator = Blockly.JSON[leftBlock.type];
            if (typeof leftGenerator === 'function') {
                leftValue = leftGenerator(leftBlock);
            } else {
                console.warn(`No generator found for block type "${leftBlock.type}". Defaulting left input to false.`);
                leftValue = false;
            }
        } else {
            console.warn("No block connected to 'LEFT' input of 'logical_or' block. Defaulting to false.");
            leftValue = false;
        }

        // Process the right input
        if (rightBlock) {
            const rightGenerator = Blockly.JSON[rightBlock.type];
            if (typeof rightGenerator === 'function') {
                rightValue = rightGenerator(rightBlock);
            } else {
                console.warn(`No generator found for block type "${rightBlock.type}". Defaulting right input to false.`);
                rightValue = false;
            }
        } else {
            console.warn("No block connected to 'RIGHT' input of 'logical_or' block. Defaulting to false.");
            rightValue = false;
        }

        // Create the logical_or operation object
        const json = {
            type: 'logical_or',
            inputs: {
                left: leftValue,
                right: rightValue
            }
        };

        return json;
    };


    /**
     * Generator for 'is_false' Block
     *
     * Generates a JSON object to check if a given condition is false.
     */
    Blockly.JSON['is_false'] = function(block) {
        // Get the connected block
        const conditionBlock = block.getInputTargetBlock('condition');

        let conditionValue = null;

        // Process the condition input
        if (conditionBlock) {
            const conditionGenerator = Blockly.JSON[conditionBlock.type];
            if (typeof conditionGenerator === 'function') {
                conditionValue = conditionGenerator(conditionBlock);
            } else {
                console.warn(`No generator found for block type "${conditionBlock.type}". Defaulting condition to false.`);
                conditionValue = false;
            }
        } else {
            console.warn("No block connected to 'condition' input of 'is_false' block. Defaulting to false.");
            conditionValue = false;
        }

        // Create the is_false operation object
        const json = {
            type: 'is_false',
            inputs: {
                condition: conditionValue
            }
        };

        return json;
    };

}
