import { 
  WorkflowDefinition, 
  WorkflowExecutor, 
  createWorkflowContext, 
  nodeRegistry, 
  BaseNode,
} from './index.js';
import { INodeContext, INodeOutput, NodeStatus, StepType } from './types/index.js';
import { InMemoryEventManager } from './event/event-manager.js';
import { ConsoleLogger } from './monitoring/logger.js';
import { LocalScheduler } from './scheduler/index.js';


// MARK: 定义简单节点
class LogNode extends BaseNode {
    id = 'LogNode';
    async execute(context: INodeContext): Promise<INodeOutput> {
        const message = context.input.message || '默认日志消息';
        console.log(`[LogNode][${context.stepId}] ${message}`, context.workflowContext.variables);
        context.logs.push(`消息已记录: ${message}`);
        return { status: NodeStatus.COMPLETED, output: { loggedAt: new Date() } };
    }
}

// MARK: 定义加法节点
class AddDataNode extends BaseNode {
    id = 'AddDataNode';
    async execute(context: INodeContext): Promise<INodeOutput> {
        const a = context.input.a ?? 0;
        const b = context.input.b ?? 0;
        const sum = Number(a) + Number(b);
        console.log(`[AddDataNode][${context.stepId}] 计算 ${a} + ${b} = ${sum}`);
        context.logs.push(`计算完成: ${sum}`);
        // 模拟可能失败的情况
        if (isNaN(sum)) {
             context.logs.push(`输入无效，计算失败`);
            return { status: NodeStatus.FAILED, error: new Error("输入不是有效的数字") };
        }
        return { status: NodeStatus.COMPLETED, output: { result: sum } };
    }
     // 添加补偿逻辑示例
     async compensate(context: INodeContext): Promise<void> {
        console.warn(`[AddDataNode][${context.stepId}] 补偿逻辑执行：尝试撤销数据添加操作 (模拟)`);
        context.logs.push("补偿操作已执行 (模拟)");
        // 在实际应用中，这里可能需要执行数据库回滚、API 调用等
    }
}

// MARK: 用户角色检查节点
class CheckUserRoleNode extends BaseNode {
    id = 'CheckUserRoleNode';
    requiredRoles = ['admin']; // 只有 admin 角色可以执行

    async execute(context: INodeContext): Promise<INodeOutput> {
        console.log(`[CheckUserRoleNode][${context.stepId}] 用户角色检查通过 (需要 admin)`);
        context.logs.push("管理员操作已执行");
        return { status: NodeStatus.COMPLETED, output: { adminActionDone: true } };
    }
}


// MARK: 注册节点
nodeRegistry.register(new LogNode());
nodeRegistry.register(new AddDataNode());
nodeRegistry.register(new CheckUserRoleNode());

// MARK: 定义工作流
const mainWorkflow = new WorkflowDefinition('main-workflow-example', '主工作流示例');

mainWorkflow
    .addStep({
        id: 'start_log',
        nodeId: 'LogNode',
        input: { message: '工作流开始' },
        nextStepId: 'calculate_sum',
    })
    .addStep({
        id: 'calculate_sum',
        nodeId: 'AddDataNode',
        input: {
            a: 'workflow.input.valueA', // 从工作流输入映射
            b: 5,                      // 静态值
        },
        outputMapping: {
            'workflow.variables.calculationResult': 'nodeOutput.result', // 将节点输出映射到工作流变量
        },
        nextStepId: 'conditional_branch',
        timeout: 5000, // 5秒超时
        maxRetries: 1, // 失败时重试1次
        retryDelay: 100, // 重试间隔100ms
        compensateOnFailure: true, // 失败时需要补偿
        sla: 1000, // SLA 为 1 秒
    })
    .addConditionStep({
        id: 'conditional_branch',
        condition: (ctx) => (ctx.variables.calculationResult ?? 0) > 10, 
        branches: {
            'true': 'log_gt_10', // 条件为 true 时跳转到 log_gt_10
            // 如果不提供 'false' 分支，且 condition 返回 false，则会尝试走 nextStepId (如果配置了)
        },
        nextStepId: 'log_le_10', // 如果条件为 false 或无匹配分支，则走到这里
    })
    .addStep({
        id: 'log_gt_10',
        nodeId: 'LogNode',
        input: { message: '计算结果大于 10' },
        nextStepId: 'parallel_tasks', // 分支结束后汇合
    })
    .addStep({
        id: 'log_le_10',
        nodeId: 'LogNode',
        input: { message: '计算结果小于或等于 10' },
        nextStepId: 'parallel_tasks', // 分支结束后汇合
    })
    .addParallelStep({
        id: 'parallel_tasks',
        parallelSteps: [
            { id: 'parallel_log_1', type: StepType.TASK, nodeId: 'LogNode', input: { message: '并行任务 1' } },
            { id: 'parallel_log_2', type: StepType.TASK, nodeId: 'LogNode', input: { message: '并行任务 2' } },
            // 可以嵌套子工作流等
            // { id: 'parallel_sub', type: StepType.SUB_WORKFLOW, subWorkflowId: 'sub_process_example' }
        ],
        nextStepId: 'admin_check',
    })
     .addStep({
        id: 'admin_check',
        nodeId: 'CheckUserRoleNode', // 需要 admin 角色
        nextStepId: 'final_log',
    })
    .addStep({
        id: 'final_log',
        nodeId: 'LogNode',
        input: { message: '工作流结束' },
        // 没有 nextStepId，工作流在此结束
    });

// MARK: 准备执行器选项和上下文
const executorOptions = {
    nodeRegistry: nodeRegistry,
    logger: new ConsoleLogger(), // 使用自定义 Logger
    eventManager: new InMemoryEventManager(), // 使用事件管理器
    scheduler: new LocalScheduler(), // 使用本地调度器
    // 使用分布式调度器占位符
    // scheduler: new DistributedSchedulerPlaceholder('rabbitmq'),
};

const initialInput = { valueA: 7 }; // 7 + 5 = 12 > 10
// const initialInput = { valueA: 3 }; // 3 + 5 = 8 <= 10
// const initialInput = { valueA: 'abc' }; // 导致 AddDataNode 失败

const workflowContext = createWorkflowContext(
    mainWorkflow.id,
    initialInput,
    'tenant-123', // 租户 ID
    'user-456',   // 用户 ID
    'admin'       // 用户角色 ('admin' 或 'user')
    // 'user'       // 如果是 'user'，admin_check 会失败
);

// 5. 创建并运行执行器
const executor = new WorkflowExecutor(mainWorkflow, workflowContext, executorOptions);

executor.run()
    .then(finalContext => {
        console.log("\n--- 工作流执行完成 ---");
        console.log("最终状态:", finalContext.status);
        console.log("最终变量:", finalContext.variables);
        if (finalContext.error) {
            console.error("最终错误:", finalContext.error);
        }
        // console.log("执行历史:", JSON.stringify(finalContext.history, null, 2)); // 打印详细历史
    })
    .catch(error => {
        console.error("\n--- 工作流执行过程中发生未捕获的严重错误 ---");
        console.error(error);
    });