import {
  IWorkflowContext, 
  INodeContext, 
  NodeStatus, 
  INodeOutput,
  StepType, 
  IExecutionRecord, 
  INode
} from '../types/index.js';
import { WorkflowDefinition } from './workflow.js';
import { Step } from './step.js';
import { NodeRegistry } from './node-register.js';
import { createNodeContext, createWorkflowContext } from './context.js';
import { 
  WorkflowError, 
  NodeExecutionError, 
  TimeoutError, 
  AuthorizationError 
} from '../errors/error.js';
// import { IScheduler } from '../scheduler/scheduler'; // 按需引入调度器
// import { IEventManager } from '../event/event-manager'; // 按需引入事件管理器
// import { ILogger } from '../monitoring/logger'; // 按需引入日志记录器

/**
* @interface WorkflowExecutorOptions
* @description 工作流执行器的配置选项
*/
export interface IWorkflowExecutorOptions {
  nodeRegistry: NodeRegistry;
  // logger?: ILogger; // 可选的日志记录器
  // eventManager?: IEventManager; // 可选的事件管理器
  // scheduler?: IScheduler; // 可选的调度器
  // workflowStore?: IWorkflowStore; // 可选的工作流存储，用于加载子工作流定义
  maxLoopIterations?: number; // 防止无限循环的最大迭代次数 (默认 1000)
}

/**
* @class WorkflowExecutor
* @description 负责执行工作流实例
*/
export class WorkflowExecutor {
  private readonly workflowDefinition: WorkflowDefinition;
  private readonly context: IWorkflowContext;
  private readonly options: Required<IWorkflowExecutorOptions>; // 使用 Required 确保所有选项都有值（提供默认值）
  private readonly nodeRegistry: NodeRegistry;
  private currentStepId: string | null;
  private executionStack: string[] = []; // 用于跟踪执行路径，辅助调试和补偿
  private compensationStack: Step[] = []; // 需要补偿的步骤栈

  constructor(
      workflowDefinition: WorkflowDefinition,
      context: IWorkflowContext,
      options: IWorkflowExecutorOptions
  ) {
      if (!workflowDefinition.validate()) {
          throw new WorkflowError(`工作流定义 "${workflowDefinition.id}" 验证失败，无法创建执行器。`);
      }
      this.workflowDefinition = workflowDefinition;
      this.context = context;
      this.nodeRegistry = options.nodeRegistry;
      this.currentStepId = this.workflowDefinition.getStartStepId();

      // 设置默认选项
      this.options = {
          nodeRegistry: options.nodeRegistry,
          // logger: options.logger ?? console, // 默认使用 console
          // eventManager: options.eventManager ?? new DefaultEventManager(),
          // scheduler: options.scheduler ?? new LocalScheduler(),
          // workflowStore: options.workflowStore ?? new InMemoryWorkflowStore(),
          maxLoopIterations: options.maxLoopIterations ?? 1000,
      };
  }

  /**
   * MARK: 开始执行工作流
   * @returns 返回最终的工作流上下文 Promise
   */
  async run(): Promise<IWorkflowContext> {
      this.log(`开始执行工作流: ${this.workflowDefinition.id} (实例 ID: ${this.context.workflowId})`);
      this.context.status = NodeStatus.RUNNING;
      this.context.startTime = this.context.startTime || new Date(); // 确保 startTime 已设置

      let iterationCount = 0; // 循环计数器

      try {
          while (this.currentStepId !== null && this.context.status === NodeStatus.RUNNING) {
              // 安全检查：防止无限循环
              if (++iterationCount > this.options.maxLoopIterations) {
                  throw new WorkflowError(`检测到可能的无限循环或执行步骤过多 (超过 ${this.options.maxLoopIterations} 次)，已中止执行。`);
              }

              const step = this.workflowDefinition.getStep(this.currentStepId);
              if (!step) {
                  throw new WorkflowError(`执行错误：在工作流 "${this.workflowDefinition.id}" 中找不到步骤 ID "${this.currentStepId}"。`);
              }

              // 权限检查
              if (!this.checkPermissions(step)) {
                  this.context.status = NodeStatus.FAILED;
                  const error = new AuthorizationError(`用户角色 "${this.context.userRole || '未定义'}" 无权执行步骤 "${step.id}" (需要: ${step.getRequiredRoles()?.join(', ')})`);
                  this.context.error = error;
                  this.recordHistory(step.id, undefined, NodeStatus.FAILED, new Date(), undefined, {}, undefined, error, [], 0);
                  this.log(`权限不足，中止执行: ${error.message}`);
                  await this.handleWorkflowFailure(step); // 触发失败处理和补偿
                  break; // 终止循环
              }

              this.executionStack.push(step.id); // 记录执行路径
              const nextStepId = await this.executeStep(step);
              this.currentStepId = nextStepId;

              // 如果执行过程中状态变为非 RUNNING (例如 FAILED, COMPLETED)，则退出循环
              if (this.context.status !== NodeStatus.RUNNING) {
                  break;
              }
          }

          // 循环结束后，更新最终状态
          if (this.context.status === NodeStatus.RUNNING) {
              // 如果循环正常结束 (currentStepId 为 null)，则标记为完成
              this.context.status = NodeStatus.COMPLETED;
              this.log(`工作流执行成功完成。`);
          }
      } catch (error: any) {
          console.error(`[Executor] 工作流 "${this.context.workflowId}" 执行期间发生严重错误:`, error);
          this.context.status = NodeStatus.FAILED;
          this.context.error = error instanceof Error ? error : new Error(String(error));
          // 尝试记录最后一步的错误历史
           if (this.currentStepId) {
               this.recordHistory(this.currentStepId, undefined, NodeStatus.FAILED, new Date(), undefined, {}, undefined, this.context.error, [`严重错误: ${this.context.error.message}`], 0);
           }
          // 尝试执行补偿逻辑
          await this.triggerCompensation();

      } finally {
          this.context.endTime = new Date();
          this.log(`工作流执行结束，最终状态: ${this.context.status}`);
          // 清理资源等（如果需要）
      }

      return this.context;
  }

  /**
   * MARK: 执行单个步骤
   * @param step - 要执行的步骤实例
   * @returns 返回下一个要执行的步骤 ID，如果工作流结束则返回 null
   */
  private async executeStep(step: Step): Promise<string | null> {
      const startTime = new Date();
      let nodeContext: INodeContext | null = null; // 延迟创建 NodeContext
      let nodeOutput: INodeOutput | null = null;
      let attempt = 0;
      let status: NodeStatus = NodeStatus.PENDING;
      let error: Error | undefined = undefined;
      let logs: string[] = [];
      let nodeInput: Record<string, any> = {};

      try {
          nodeInput = this.resolveInput(step); // 解析输入映射
          nodeContext = createNodeContext(this.context, step.id, step.getNodeId(), nodeInput);
          logs.push(`开始执行步骤: ${step.id} (类型: ${step.type})`);

          // --- 核心执行逻辑分发 ---
          switch (step.type) {
              case StepType.TASK:
                  nodeOutput = await this.executeTaskStep(step, nodeContext);
                  break;
              case StepType.CONDITION:
                  nodeOutput = this.executeConditionStep(step, nodeContext);
                  break;
              case StepType.PARALLEL:
                  nodeOutput = await this.executeParallelStep(step, nodeContext);
                  break;
              case StepType.SUB_WORKFLOW:
                  nodeOutput = await this.executeSubWorkflowStep(step, nodeContext);
                  break;
              case StepType.EVENT_TRIGGER:
                  nodeOutput = await this.executeEventTriggerStep(step, nodeContext);
                  break;
              // EVENT_LISTENER 通常不由执行器主动执行，而是由外部事件触发
              default:
                  throw new WorkflowError(`不支持的步骤类型: ${step.type}`);
          }

          status = nodeOutput.status;
          if (nodeOutput.error) error = nodeOutput.error;
          if (nodeOutput.output) nodeContext.output = nodeOutput.output; // 更新节点上下文输出

          // 处理输出映射
          this.resolveOutput(step, nodeContext);

          // 记录成功或跳过的步骤到补偿栈 (如果需要)
          if (status === NodeStatus.COMPLETED && step.getCompensateOnFailure() ) {
               this.compensationStack.push(step);
          }

      } catch (err: any) {
          status = NodeStatus.FAILED;
          error = err instanceof Error ? err : new Error(String(err));
          logs.push(`步骤 ${step.id} 执行失败: ${error.message}`);
          console.error(`[Executor] 步骤 ${step.id} 执行失败:`, error);
          // 可以在这里添加重试逻辑，但通常在 executeTaskStep 内部处理更合适
      } finally {
          // 确保 nodeContext 存在才更新状态和记录历史
           if (nodeContext) {
               nodeContext.status = status;
               nodeContext.error = error;
               nodeContext.endTime = new Date();
               nodeContext.logs.push(...logs); // 合并日志

               // 记录执行历史
               this.recordHistory(
                   step.id,
                   step.getNodeId(),
                   status,
                   startTime,
                   nodeContext.endTime,
                   nodeInput, // 记录解析后的输入
                   nodeContext.output,
                   error,
                   nodeContext.logs,
                   attempt // 记录尝试次数 (重试逻辑应更新此值)
               );

               // 检查 SLA
               this.checkSLA(step, startTime, nodeContext.endTime, status);
           } else {
               // 如果连 nodeContext 都没创建就失败了 (例如输入解析失败)
               this.recordHistory(step.id, undefined, NodeStatus.FAILED, startTime, new Date(), nodeInput, undefined, error ?? new Error("步骤初始化失败"), logs, 0);
           }
      }

      // --- 处理步骤结果，决定下一步 ---
      if (status === NodeStatus.COMPLETED || status === NodeStatus.SKIPPED) {
          this.log(`步骤 ${step.id} 完成，状态: ${status}`);
          // 对于条件步骤，需要根据结果确定分支
          if (step.type === StepType.CONDITION && status === NodeStatus.COMPLETED) {
              const branchKey = nodeContext?.output?.branch; // 条件执行结果存储在 output.branch
              if (typeof branchKey === 'string') {
                  return step.getBranchTarget(branchKey);
              } else {
                  // 如果条件为 false 或无匹配分支，则可能跳到 nextStepId 或结束
                  return step.nextStepId ?? null; // 或者根据具体逻辑决定
              }
          }
          // 其他成功或跳过的步骤，直接进入下一步
          return step.nextStepId ?? null; // 如果没有 nextStepId，则工作流结束
      } else if (status === NodeStatus.FAILED || status === NodeStatus.TIMEOUT) {
           this.log(`步骤 ${step.id} 失败或超时，状态: ${status}`);
           await this.handleStepFailure(step, nodeContext); // 处理失败/超时
           // 失败后，除非有特殊处理，否则工作流通常会停止
           this.context.status = NodeStatus.FAILED; // 设置工作流状态为失败
           this.context.error = error ?? new Error(`步骤 ${step.id} 执行失败`);
           return null; // 终止执行
      } else {
          // 其他状态 (如 RUNNING - 不应在此处出现, PENDING - 也不应出现)
          throw new WorkflowError(`步骤 ${step.id} 执行后处于意外状态: ${status}`);
      }
  }

  /**
   * MARK: 执行TASK
   */
  private async executeTaskStep(step: Step, context: INodeContext): Promise<INodeOutput> {
      const nodeId = step.getNodeId();
      if (!nodeId) {
          throw new WorkflowError(`任务步骤 "${step.id}" 未配置 nodeId。`);
      }
      const node = this.nodeRegistry.get(nodeId);
      if (!node) {
          throw new WorkflowError(`任务步骤 "${step.id}" 配置的节点 "${nodeId}" 未注册。`);
      }

      // 输入验证 (可选)
      if (node.validateInput && !node.validateInput(context.input)) {
           context.logs.push(`节点 ${nodeId} 输入验证失败。`);
           return { status: NodeStatus.FAILED, error: new Error(`节点 ${nodeId} 输入验证失败。`) };
      }

      let result: INodeOutput = { status: NodeStatus.PENDING };
      const maxRetries = step.getMaxRetries();
      const retryDelay = step.getRetryDelay();
      const timeout = step.getTimeout();

      for (let attempt = 0; attempt <= maxRetries; attempt++) {
          context.retries = attempt; // 更新上下文中的重试次数
          context.startTime = new Date(); // 每次尝试都重置开始时间
          context.logs.push(`开始尝试执行节点 ${nodeId} (尝试次数: ${attempt + 1}/${maxRetries + 1})`);

          try {
              let executionPromise = node.execute(context);

              // 处理超时
              if (timeout && timeout > 0) {
                  const timeoutPromise = new Promise<INodeOutput>((_, reject) =>
                      setTimeout(() => reject(new TimeoutError(`节点 ${nodeId} 执行超时 (${timeout}ms)`)), timeout)
                  );
                  result = await Promise.race([executionPromise, timeoutPromise]);
              } else {
                  result = await executionPromise;
              }

              context.endTime = new Date();
              context.status = result.status;
              context.output = result.output;
              context.error = result.error;
               context.logs.push(`节点 ${nodeId} 尝试 ${attempt + 1} 完成，状态: ${result.status}`);

              // 如果成功或跳过，则跳出重试循环
              if (result.status === NodeStatus.COMPLETED || result.status === NodeStatus.SKIPPED) {
                  break;
              }
              // 如果失败，且还有重试次数，则准备下一次重试
              if (result.status === NodeStatus.FAILED && attempt < maxRetries) {
                   context.logs.push(`节点 ${nodeId} 失败，将在 ${retryDelay}ms 后重试...`);
                   if (retryDelay > 0) {
                       await new Promise(resolve => setTimeout(resolve, retryDelay));
                   }
              }

          } catch (err: any) {
              context.endTime = new Date();
              result = {
                  status: err instanceof TimeoutError ? NodeStatus.TIMEOUT : NodeStatus.FAILED,
                  error: err instanceof Error ? err : new Error(String(err))
              };
              context.status = result.status;
              context.error = result.error;
              context.logs.push(`节点 ${nodeId} 尝试 ${attempt + 1} 发生异常: ${result.error?.message}`);

               // 如果还有重试次数，准备下一次重试
               if (result.status !== NodeStatus.TIMEOUT && attempt < maxRetries) { // 超时通常不重试，除非特殊配置
                  context.logs.push(`节点 ${nodeId} 异常，将在 ${retryDelay}ms 后重试...`);
                  if (retryDelay > 0) {
                      await new Promise(resolve => setTimeout(resolve, retryDelay));
                  }
               } else {
                   // 没有重试次数了或发生超时，跳出循环
                   break;
               }
          }
      } // end for loop (retries)

      return result;
  }

  /**
   * MARK: 执行条件
   * 执行 CONDITION 类型的步骤
   */
  private executeConditionStep(step: Step, context: INodeContext): INodeOutput {
      try {
          const conditionResult = step.evaluateCondition(this.context); // 条件在工作流上下文上评估
          context.logs.push(`条件评估结果: ${conditionResult}`);

          if (typeof conditionResult === 'boolean') {
              if (conditionResult) {
                  // 条件为 true，继续执行 nextStepId
                  context.logs.push(`条件为 true，继续执行。`);
                  return { status: NodeStatus.COMPLETED, output: { conditionMet: true } };
              } else {
                  // 条件为 false，跳过 nextStepId (或者根据设计决定是否算作完成)
                  // 这里我们认为条件不满足也是一种“完成”，但可能需要跳过后续步骤
                  context.logs.push(`条件为 false，跳过后续分支。`);
                  // 返回 SKIPPED 状态可能更合适，取决于具体语义
                  // return { status: NodeStatus.SKIPPED, output: { conditionMet: false } };
                  // 或者返回 COMPLETED，由调用者决定下一步是 null 还是 nextStepId
                   return { status: NodeStatus.COMPLETED, output: { conditionMet: false, branch: false } }; // 使用 output 传递结果
              }
          } else if (typeof conditionResult === 'string') {
              // 条件结果是一个分支键名
              context.logs.push(`条件满足，选择分支: ${conditionResult}`);
              // 将分支键名放入输出，以便 run 方法决定下一个 stepId
              return { status: NodeStatus.COMPLETED, output: { branch: conditionResult } };
          } else {
               // evaluateCondition 内部应该已抛出错误，这里再加一层保险
               throw new Error("无效的条件评估结果类型");
          }
      } catch (error: any) {
          return { status: NodeStatus.FAILED, error: error };
      }
  }

  /**
   * MARK: 执行并行
   * 执行 PARALLEL 类型的步骤
   */
  private async executeParallelStep(step: Step, context: INodeContext): Promise<INodeOutput> {
      const parallelStepConfigs = step.getParallelSteps();
      context.logs.push(`开始执行并行步骤 (${parallelStepConfigs.length} 个分支)`);

      const promises: Promise<IWorkflowContext>[] = []; // 每个并行分支都是一个独立的“迷你”工作流执行

      for (const stepConfig of parallelStepConfigs) {
          // 为每个并行分支创建一个新的 "子执行器" 或模拟执行流程
          // 注意：真正的并行执行可能需要更复杂的上下文管理和状态合并
          // 这里简化处理：假设每个分支都是从该并行步骤开始的独立序列

          // 简单的模拟：为每个分支创建一个临时的 WorkflowDefinition 和 Executor
          // 这不是最高效的方式，但演示了概念
          const branchWorkflowDef = new WorkflowDefinition(`parallel_branch_${stepConfig.id}`);
          branchWorkflowDef.addStepInternal(stepConfig); // 添加分支的第一个步骤
          // TODO: 需要处理分支后续的步骤链接

           // 创建分支的上下文，继承父工作流的部分信息，但有独立的变量空间可能更好
           const branchParentContext = { ...this.context, variables: { ...this.context.variables } };
           const branchInput = this.resolveInput(new Step(stepConfig), branchParentContext); // 解析分支输入
           const branchContext = createWorkflowContext(
               branchWorkflowDef.id,
               branchInput,
               this.context.tenantId,
               this.context.userId,
               this.context.userRole
           );
           // 传递父工作流的变量给分支上下文
           branchContext.variables = { ...this.context.variables };

           const branchExecutor = new WorkflowExecutor(branchWorkflowDef, branchContext, this.options);

           // 启动分支执行，并将 Promise 添加到数组
           // 注意：这里假设 run() 返回最终的上下文
           promises.push(branchExecutor.run());

           // 更复杂的实现可能需要：
           // 1. 共享的上下文或状态同步机制
           // 2. 更好的错误处理（一个分支失败是否影响其他分支？）
           // 3. 结果合并策略
      }

      try {
          const results = await Promise.all(promises); // 等待所有并行分支完成

          // 合并结果和状态
          let finalStatus: NodeStatus = NodeStatus.COMPLETED;
          const mergedOutputs: Record<string, any> = {};
          const branchErrors: Error[] = [];

          results.forEach((branchContext, index) => {
              const branchStepId = parallelStepConfigs[index].id;
              mergedOutputs[branchStepId] = branchContext.output; // 合并输出
              if (branchContext.status === NodeStatus.FAILED || branchContext.status === NodeStatus.TIMEOUT) {
                  finalStatus = NodeStatus.FAILED; // 如果任何一个分支失败，则整个并行步骤失败
                  if (branchContext.error) {
                      branchErrors.push(new Error(`并行分支 ${branchStepId} 失败: ${branchContext.error.message}`));
                  } else {
                       branchErrors.push(new Error(`并行分支 ${branchStepId} 失败，状态: ${branchContext.status}`));
                  }
              }
              // 合并变量? (需要策略：覆盖、合并等)
              // this.context.variables = { ...this.context.variables, ...branchContext.variables };
               context.logs.push(`并行分支 ${branchStepId} 完成，状态: ${branchContext.status}`);
          });


          // FIXME: 需要处理并行分支的错误
          if (branchErrors.length > 0) {
              const combinedError = new Error(`一个或多个并行分支执行失败。\n${branchErrors.map(e => e.message).join('\n')}`);
              return { status: NodeStatus.FAILED, output: mergedOutputs, error: combinedError };
          } else {
              context.logs.push(`所有并行分支执行成功。`);
              return { status: NodeStatus.COMPLETED, output: mergedOutputs };
          }

      } catch (error: any) {
          // Promise.all 的错误处理
          context.logs.push(`执行并行步骤时发生错误: ${error.message}`);
          return { status: NodeStatus.FAILED, error: error };
      }
  }

  /**
   * MARK: 执行子工作流
   * 执行 SUB_WORKFLOW 类型的步骤
   */
  private async executeSubWorkflowStep(step: Step, context: INodeContext): Promise<INodeOutput> {
      const subWorkflowId = step.getSubWorkflowId();
      const subWorkflowInput = this.resolveInput(step); // 使用 resolveInput 处理输入映射

      context.logs.push(`开始执行子工作流: ${subWorkflowId}`);

      // TODO: 需要实现从存储中加载子工作流定义的功能
      // const subWorkflowDef = await this.options.workflowStore.getDefinition(subWorkflowId);
      const subWorkflowDef = this.loadSubWorkflowDefinition(subWorkflowId); // 假设有这个方法

      if (!subWorkflowDef) {
          return { status: NodeStatus.FAILED, error: new WorkflowError(`子工作流定义 "${subWorkflowId}" 未找到。`) };
      }

      // 创建子工作流的上下文
      const subContext = createWorkflowContext(
          subWorkflowId,
          subWorkflowInput,
          this.context.tenantId, // 继承租户和用户信息
          this.context.userId,
          this.context.userRole
      );
      // 决定是否以及如何传递父工作流变量给子工作流 (可选)
      // subContext.variables = { ...this.context.variables }; // 示例：完全继承

      // 创建并运行子工作流执行器
      const subExecutor = new WorkflowExecutor(subWorkflowDef, subContext, this.options);
      const subResultContext = await subExecutor.run();

      context.logs.push(`子工作流 ${subWorkflowId} 执行完成，状态: ${subResultContext.status}`);

      // 将子工作流的结果映射回父工作流
      if (subResultContext.status === NodeStatus.COMPLETED) {
          // 将子工作流的输出作为此步骤的输出
          return { status: NodeStatus.COMPLETED, output: subResultContext.output };
      } else {
          // 如果子工作流失败，则此步骤也失败
          const error = subResultContext.error ?? new Error(`子工作流 "${subWorkflowId}" 执行失败，状态: ${subResultContext.status}`);
          return { status: NodeStatus.FAILED, error: error };
      }
  }

   /**
    * MARK: 执行事件触发
   * 执行 EVENT_TRIGGER 类型的步骤
   */
   private async executeEventTriggerStep(step: Step, context: INodeContext): Promise<INodeOutput> {
      const eventName = step.getEventName();
      const eventData = this.resolveInput(step); // 事件数据通常来自步骤输入

      context.logs.push(`触发事件: ${eventName}`);

      // TODO: 需要与 EventManager 集成
      // await this.options.eventManager?.emit(eventName, eventData, this.context);

      console.log(`[Executor] 事件已触发 (模拟): ${eventName}`, eventData);

      // 事件触发步骤通常立即完成
      return { status: NodeStatus.COMPLETED, output: { eventTriggered: eventName } };
  }

  // --- 辅助方法 ---

  /**
   * MARK: 记录执行历史
   * 记录执行历史
   */
  private recordHistory(
      stepId: string, nodeId: string | undefined, status: NodeStatus,
      startTime: Date, endTime: Date | undefined, input: Record<string, any>,
      output: Record<string, any> | undefined, error: Error | undefined,
      logs: string[], attempt: number
  ): void {
      const record: IExecutionRecord = {
          stepId,
          nodeId,
          status,
          startTime,
          endTime,
          input,
          output,
          error: error?.message, // 只记录错误消息
          logs: [...logs], // 复制日志数组
          attempt
      };
      this.context.history.push(record);
      this.log(`[History] 步骤 ${stepId} (${status})`); // 简化日志输出
  }

  /**
   * MARK: 解析输入
   * NOTE: 解析步骤的输入数据，支持从工作流变量映射
   * @param step - 当前步骤
   * @param currentContext - 可选，用于解析的上下文，默认为 this.context
   * @returns 解析后的输入对象
   */
  private resolveInput(step: Step, currentContext: IWorkflowContext = this.context): Record<string, any> {
      const inputConfig = step.getInputConfig();
      if (!inputConfig) {
          return {}; // 没有配置输入，返回空对象
      }

      const resolvedInput: Record<string, any> = {};
      try {
          for (const key in inputConfig) {
              const valueOrPath = inputConfig[key];
              if (typeof valueOrPath === 'string' && valueOrPath.startsWith('workflow.')) {
                  // 从工作流上下文中解析路径
                  resolvedInput[key] = this.resolveContextPath(currentContext, valueOrPath);
              } else {
                  // 直接使用静态值
                  resolvedInput[key] = valueOrPath;
              }
          }
      } catch (error: any) {
           console.error(`[Executor] 解析步骤 ${step.id} 的输入时出错:`, error);
           // 抛出错误，让上层处理失败
           throw new NodeExecutionError(`解析步骤 ${step.id} 的输入配置 "${JSON.stringify(inputConfig)}" 时失败: ${error.message}`);
      }
      return resolvedInput;
  }

  /**
   * MARK: 解析输出
   * NOTE: 将节点输出映射回工作流变量
   * @param step - 当前步骤
   * @param nodeContext - 节点执行上下文 (包含输出)
   */
  private resolveOutput(step: Step, nodeContext: INodeContext | null): void {
      const outputMapping = step.getOutputMapping();
      if (!outputMapping || !nodeContext || nodeContext.status !== NodeStatus.COMPLETED || !nodeContext.output) {
          return; // 没有映射或节点未成功完成或无输出，则不执行映射
      }

      try {
          for (const workflowVarPath in outputMapping) {
              const nodeOutputPath = outputMapping[workflowVarPath];
              const valueToMap = this.resolveContextPath(nodeContext, nodeOutputPath); // 从节点上下文中解析值

              // 将值设置到工作流上下文中
              this.setContextPath(this.context, workflowVarPath, valueToMap);
          }
      } catch (error: any) {
          console.error(`[Executor] 解析步骤 ${step.id} 的输出映射时出错:`, error);
          // 记录警告或错误，但不一定中止工作流
          nodeContext.logs.push(`警告：解析输出映射失败: ${error.message}`);
      }
  }

  /**
   * MARK: 解析路径
   * NOTE: 根据路径字符串从上下文中获取值 (例如 "variables.user.name")
   * @param context - IWorkflowContext 或 INodeContext
   * @param path - 路径字符串
   * @returns 解析到的值，如果路径无效则可能返回 undefined 或抛出错误
   */
  private resolveContextPath(context: any, path: string): any {
      // 移除前缀 "workflow." 或 "nodeOutput." (如果存在)
      const cleanPath = path.replace(/^(workflow|nodeOutput)\./, '');
      const parts = cleanPath.split('.');
      let current = context;
      for (const part of parts) {
          if (current === null || typeof current !== 'object') {
               throw new Error(`无法解析路径 "${path}"，在 "${part}" 部分遇到非对象值。`);
             // return undefined; // 或者返回 undefined
          }
          current = current[part];
      }
      return current;
  }

  /**
   * MARK: 设置路径
   * NOTE: 根据路径字符串向上下文中设置值 (例如 "variables.result.data")
   * @param context - IWorkflowContext (通常是这个)
   * @param path - 路径字符串
   * @param value - 要设置的值
   */
  private setContextPath(context: any, path: string, value: any): void {
      // 移除前缀 "workflow."
      const cleanPath = path.replace(/^workflow\./, '');
      const parts = cleanPath.split('.');
      let current = context;
      for (let i = 0; i < parts.length - 1; i++) {
          const part = parts[i];
          if (current[part] === undefined || typeof current[part] !== 'object') {
              current[part] = {}; // 如果路径不存在或不是对象，则创建空对象
          }
          current = current[part];
      }
      current[parts[parts.length - 1]] = value;
  }


  /**
   * MARK: 处理失败或超时
   * 处理步骤失败或超时
   */
  private async handleStepFailure(step: Step, nodeContext: INodeContext | null): Promise<void> {
      this.log(`处理步骤 ${step.id} 的失败/超时...`);
      // 可以在这里触发事件、发送通知等

      // 检查是否需要补偿
      const compensateSetting = step.getCompensateOnFailure();
      if (compensateSetting) {
          if (typeof compensateSetting === 'string') {
              // 跳转到指定的补偿步骤 (暂未实现跳转逻辑)
              this.log(`需要跳转到补偿步骤: ${compensateSetting} (暂未实现)`);
          } else {
              // 触发当前步骤或整个工作流的回滚/补偿
              await this.triggerCompensation(step); // 从当前失败的步骤开始补偿
          }
      }
  }

   /**
    * MARK: 工作流失败
   * 处理整个工作流失败（例如权限不足或严重错误）
   */
    private async handleWorkflowFailure(failedStep?: Step): Promise<void> {
      this.log(`处理工作流 ${this.context.workflowId} 的失败...`);
      // 触发补偿逻辑，从最后一个成功（且需要补偿）的步骤开始，或者从指定的失败步骤开始
      await this.triggerCompensation(failedStep);
  }


  /**
   * MARK: 触发补偿
   * 触发补偿逻辑
   * @param failedStep 可选，如果提供了，则从该步骤关联的节点开始补偿（如果该节点有补偿逻辑）
   * 否则，按补偿栈顺序回滚
   */
  private async triggerCompensation(failedStep?: Step): Promise<void> {
      this.log(`开始补偿流程...`);
      this.context.status = NodeStatus.COMPENSATING; // 标记工作流正在补偿

      if (failedStep) {
           const nodeId = failedStep.getNodeId();
           if (nodeId) {
               const node = this.nodeRegistry.get(nodeId);
               // 查找失败步骤对应的执行记录以获取上下文
               const failedRecord = this.context.history.find(h => h.stepId === failedStep.id && h.status === NodeStatus.FAILED);
               if (node?.compensate && failedRecord) {
                   try {
                       this.log(`尝试补偿失败的节点: ${nodeId} (步骤: ${failedStep.id})`);
                       // 创建补偿用的节点上下文
                       const compensationNodeContext = createNodeContext(
                           this.context,
                           failedStep.id,
                           nodeId,
                           failedRecord.input // 使用失败时的输入
                       );
                       compensationNodeContext.status = NodeStatus.COMPENSATING; // 标记节点正在补偿
                       compensationNodeContext.output = failedRecord.output; // 传递之前的输出（如果有）
                       compensationNodeContext.error = this.context.error; // 传递错误信息

                       await node.compensate(compensationNodeContext);
                       this.log(`节点 ${nodeId} 补偿完成。`);
                       // 更新历史记录？或者添加补偿记录？
                   } catch (compensationError: any) {
                       this.log(`节点 ${nodeId} 补偿失败: ${compensationError.message}`);
                       // 补偿失败的处理？记录日志，可能中止补偿
                   }
               }
           }
      }


      // 按补偿栈逆序执行补偿
      while (this.compensationStack.length > 0) {
          const stepToCompensate = this.compensationStack.pop()!;
          const nodeId = stepToCompensate.getNodeId();
          if (!nodeId) continue; // 只有 TASK 节点通常有补偿逻辑

          const node = this.nodeRegistry.get(nodeId);
           // 查找该步骤最后一次成功的执行记录
           const lastSuccessRecord = [...this.context.history]
              .reverse()
              .find(h => h.stepId === stepToCompensate.id && h.status === NodeStatus.COMPLETED);

          if (node?.compensate && lastSuccessRecord) {
              try {
                  this.log(`开始补偿步骤: ${stepToCompensate.id} (节点: ${nodeId})`);
                  const compensationNodeContext = createNodeContext(
                      this.context,
                      stepToCompensate.id,
                      nodeId,
                      lastSuccessRecord.input // 使用成功执行时的输入
                  );
                  compensationNodeContext.status = NodeStatus.COMPENSATING;
                  compensationNodeContext.output = lastSuccessRecord.output; // 传递成功执行的输出

                  await node.compensate(compensationNodeContext);
                  this.log(`步骤 ${stepToCompensate.id} 补偿完成。`);
                  // 更新历史记录或添加补偿记录
                  this.recordHistory(stepToCompensate.id, nodeId, NodeStatus.COMPENSATED, new Date(), new Date(), compensationNodeContext.input, undefined, undefined, [`补偿操作已执行`], 0);

              } catch (compensationError: any) {
                  this.log(`步骤 ${stepToCompensate.id} 补偿失败: ${compensationError.message}`);
                  // 补偿失败，是否应该停止？或者继续补偿其他步骤？
                  // 记录错误，可能需要人工干预
                   this.recordHistory(stepToCompensate.id, nodeId, NodeStatus.FAILED, new Date(), new Date(), lastSuccessRecord.input, undefined, compensationError, [`补偿操作失败: ${compensationError.message}`], 0);
                   // 决定是否中止整个补偿流程
                   // break;
              }
          }
      }

       // 补偿流程结束后，最终状态仍是 FAILED (除非补偿逻辑能恢复到某个状态)
       this.context.status = NodeStatus.FAILED; // 或者根据补偿结果决定
       this.log(`补偿流程结束。`);
  }

  /**
   * MARK: 检查权限
   * 检查权限
   */
  private checkPermissions(step: Step): boolean {
      const requiredRoles = step.getRequiredRoles();
      if (!requiredRoles || requiredRoles.length === 0) {
          return true; // 没有设置权限要求，允许执行
      }
      const userRole = this.context.userRole;
      if (!userRole) {
          this.log(`警告：步骤 ${step.id} 需要角色 ${requiredRoles.join(', ')}，但未提供用户角色。拒绝执行。`);
          return false; // 需要角色但用户没有角色
      }
      // 简单检查：用户角色是否在所需角色列表中
      // 更复杂的场景可能需要查询用户的角色列表
      if (requiredRoles.includes(userRole)) {
          return true;
      } else {
          this.log(`权限检查失败：步骤 ${step.id} 需要角色 ${requiredRoles.join(', ')}，用户角色为 ${userRole}。`);
          return false;
      }
  }

  /**
   * MARK: 检查 SLA
   * 检查 SLA
   */
  private checkSLA(step: Step, startTime: Date, endTime: Date | undefined, status: NodeStatus): void {
      const sla = step.getSla();
      if (sla && endTime && status !== NodeStatus.TIMEOUT) { // 只在未超时且有 SLA 配置时检查
          const duration = endTime.getTime() - startTime.getTime();
          if (duration > sla) {
              const slaViolationMsg = `SLA 违约：步骤 ${step.id} 执行耗时 ${duration}ms，超过 SLA ${sla}ms。`;
              this.log(`警告: ${slaViolationMsg}`);
              // TODO: 触发 SLA 违约通知或事件
              // this.options.eventManager?.emit('sla.violation', { stepId: step.id, duration, sla, workflowId: this.context.workflowId });
               // 在节点日志中也记录一下
               const nodeContext = this.context.history[this.context.history.length - 1]; // 获取最后一条记录
               if (nodeContext?.logs) {
                   nodeContext.logs.push(`[SLA Violation] ${slaViolationMsg}`);
               }
          }
      }
       // 超时本身也是一种 SLA 违约
       if (status === NodeStatus.TIMEOUT) {
          const timeoutMsg = `SLA 违约 (超时)：步骤 ${step.id} 执行超时。`;
          this.log(`警告: ${timeoutMsg}`);
          // TODO: 触发超时通知
          // this.options.eventManager?.emit('sla.violation.timeout', { stepId: step.id, timeout: step.getTimeout(), workflowId: this.context.workflowId });
          const nodeContext = this.context.history[this.context.history.length - 1];
          if (nodeContext?.logs) {
              nodeContext.logs.push(`[SLA Violation] ${timeoutMsg}`);
          }
       }
  }


  /**
   * MARK: 加载子工作流
   * NOTE: 实际应从存储加载
   */
  private loadSubWorkflowDefinition(subWorkflowId: string): WorkflowDefinition | undefined {
      console.warn(`[Executor] 正在模拟加载子工作流定义: ${subWorkflowId} (需要实现真实加载逻辑)`);
      // 示例：假设有一个预定义的子工作流
      if (subWorkflowId === 'sub_process_example') {
          const subDef = new WorkflowDefinition(subWorkflowId, '示例子流程');
          subDef.addStep({ id: 'sub_task_1', nodeId: 'LogNode', input: { message: '子流程任务 1 执行' } })
                .addStep({ id: 'sub_task_2', nodeId: 'LogNode', input: { message: '子流程任务 2 执行' }, nextStepId: 'sub_task_1' }); // 故意写反，让 validate 失败
          subDef.setStartStep('sub_task_1'); // 设置起始
           // 在实际应用中，加载后应该验证
           // if (!subDef.validate()) {
           //     console.error(`加载的子工作流 ${subWorkflowId} 验证失败。`);
           //     return undefined;
           // }
          return subDef;
      }
      return undefined;
  }

  /**
   * MARK: 日志
   * NOTE: 简单的日志记录方法
   */
  private log(message: string): void {
      // TODO: 集成真实的 Logger
      console.log(`[Executor][${this.context.workflowId}] ${message}`);
      // 可以在这里将日志添加到工作流上下文的全局日志中
      // this.context.logs = this.context.logs || [];
      // this.context.logs.push(`[${new Date().toISOString()}] ${message}`);
  }
}