"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.playStepsExecutor = void 0;
const stepIndexUtils_1 = require("../../sharedUtils/stepIndexUtils");
const mablscript_step_types_1 = require("../../sharedUtils/mablscript-step-types");
exports.playStepsExecutor = {
    needsFind: () => false,
    getStepType: () => 'play_steps',
    execute: async (payload, stateProvider, eventHandler, logger) => {
        const toolParams = payload.toolCall.toolParams;
        const startStepIndex = toolParams?.start_step_index;
        const endStepIndex = toolParams?.end_step_index;
        const continueOnFailure = toolParams?.continue_on_failure ?? false;
        if (!startStepIndex || !endStepIndex) {
            return {
                success: false,
                errorCause: 'IllegalArguments',
                errorMessage: 'Both start_step_index and end_step_index are required (1-based dot-notation, e.g. "1", "3.2")',
            };
        }
        let startPath;
        let endPath;
        try {
            startPath = (0, stepIndexUtils_1.parseStepIndex)(startStepIndex);
            endPath = (0, stepIndexUtils_1.parseStepIndex)(endStepIndex);
        }
        catch (error) {
            return {
                success: false,
                errorCause: 'IllegalArguments',
                errorMessage: error instanceof Error ? error.message : 'Invalid step index format',
            };
        }
        const allSteps = stateProvider.getSteps();
        const getNestedSteps = (0, stepIndexUtils_1.createNestedStepResolver)(stateProvider.getImportedFlowSteps.bind(stateProvider));
        let stepsInRange;
        try {
            stepsInRange = (0, stepIndexUtils_1.collectStepsInRange)(allSteps, startPath, endPath, getNestedSteps);
        }
        catch (error) {
            return {
                success: false,
                errorCause: 'IllegalArguments',
                errorMessage: error instanceof Error ? error.message : 'Invalid step range',
            };
        }
        const failedIndices = [];
        let conditionalSkipDepth = 0;
        for (const { step, index } of stepsInRange) {
            if (getNestedSteps(step) !== undefined) {
                continue;
            }
            if (conditionalSkipDepth > 0) {
                if ((0, mablscript_step_types_1.isIfOrElseIfStep)(step)) {
                    conditionalSkipDepth++;
                    logger.info(`Skipping nested conditional step ${index} (depth ${conditionalSkipDepth})`);
                    continue;
                }
                if ((0, mablscript_step_types_1.isEndStep)(step)) {
                    conditionalSkipDepth--;
                    if (conditionalSkipDepth === 0) {
                        logger.info(`Reached END at step ${index}; resuming execution after conditional block`);
                        continue;
                    }
                    logger.info(`Skipping nested END at step ${index} (depth ${conditionalSkipDepth})`);
                    continue;
                }
                if ((0, mablscript_step_types_1.isElseStep)(step) && conditionalSkipDepth === 1) {
                    conditionalSkipDepth = 0;
                    logger.info(`Reached ELSE at step ${index}; resuming execution in ELSE branch`);
                    continue;
                }
                if ((0, mablscript_step_types_1.isIfOrElseIfStep)(step) || (0, mablscript_step_types_1.isElseStep)(step)) {
                    continue;
                }
                logger.info(`Skipping step ${index} (inside false conditional branch)`);
                continue;
            }
            if ((0, mablscript_step_types_1.isElseStep)(step)) {
                conditionalSkipDepth = 1;
                logger.info(`Preceding branch was true; skipping ELSE body at step ${index}`);
                continue;
            }
            if ((0, mablscript_step_types_1.isEndStep)(step)) {
                continue;
            }
            try {
                const result = await eventHandler.runSingleStep(step);
                if (result.success === false) {
                    if ((0, mablscript_step_types_1.isIfOrElseIfStep)(step)) {
                        conditionalSkipDepth = 1;
                        logger.info(`Conditional step ${index} evaluated to false; skipping branch until ELSE/END`);
                        continue;
                    }
                    if ((0, mablscript_step_types_1.isAnyConditionalControlFlowStep)(step)) {
                        logger.info(`Control-flow step ${index} result ignored during replay`);
                        continue;
                    }
                    logger.warn(`Step ${index} failed during replay: ${result.message ?? 'no details'}`);
                    if (!continueOnFailure) {
                        const failedPath = (0, stepIndexUtils_1.parseStepIndex)(index);
                        const cursorAfterFailed = [...failedPath];
                        cursorAfterFailed[cursorAfterFailed.length - 1] += 1;
                        eventHandler.setNextStepIndex(cursorAfterFailed);
                        return {
                            success: false,
                            errorMessage: `Replay failed at step ${index}. Cursor is now at ${(0, stepIndexUtils_1.pathToStepIndex)(cursorAfterFailed)}.`,
                        };
                    }
                    failedIndices.push(index);
                }
                else if ((0, mablscript_step_types_1.isIfOrElseIfStep)(step)) {
                    logger.info(`Conditional step ${index} evaluated to true; executing branch`);
                }
            }
            catch (error) {
                if ((0, mablscript_step_types_1.isAnyConditionalControlFlowStep)(step)) {
                    if ((0, mablscript_step_types_1.isIfOrElseIfStep)(step)) {
                        conditionalSkipDepth = 1;
                    }
                    logger.info(`Conditional step ${index} threw during replay; treating as not-a-failure: ${error instanceof Error ? error.message : 'unknown error'}`);
                    continue;
                }
                logger.error(`Error replaying step ${index}:`, error);
                if (!continueOnFailure) {
                    const failedPath = (0, stepIndexUtils_1.parseStepIndex)(index);
                    const cursorAfterFailed = [...failedPath];
                    cursorAfterFailed[cursorAfterFailed.length - 1] += 1;
                    eventHandler.setNextStepIndex(cursorAfterFailed);
                    return {
                        success: false,
                        errorMessage: `Replay failed at step ${index}. Cursor is now at ${(0, stepIndexUtils_1.pathToStepIndex)(cursorAfterFailed)}.`,
                    };
                }
                failedIndices.push(index);
            }
        }
        const newCursor = [...endPath];
        newCursor[newCursor.length - 1] += 1;
        eventHandler.setNextStepIndex(newCursor);
        const cursorLabel = (0, stepIndexUtils_1.pathToStepIndex)(newCursor);
        if (failedIndices.length > 0) {
            logger.info(`Replayed steps ${startStepIndex} to ${endStepIndex} with ${failedIndices.length} failure(s)`);
            return {
                success: false,
                errorMessage: `Replayed steps ${startStepIndex}-${endStepIndex}. Steps ${failedIndices.join(', ')} failed. Cursor is now at ${cursorLabel}.`,
                failed_steps: failedIndices,
            };
        }
        logger.info(`Replayed steps ${startStepIndex} to ${endStepIndex}`);
        return {
            success: true,
            message: `Replayed steps ${startStepIndex}-${endStepIndex}. Cursor is now at ${cursorLabel}.`,
        };
    },
};
