/**
 * 流程执行器
 * 管理和执行节点流程
 */

import { getNodeMetadataByType } from '../utils/nodeMetadata';

export class FlowExecutor {
  constructor() {
    this.executionContext = {};
    this.executionHistory = [];
    this.isExecuting = false;
    
    // 预构建的执行路径映射
    this.executionPaths = new Map();
    this.conditionNodes = new Map();
  }

  /**
   * 执行流程
   * @param {Array} nodes - 节点数组
   * @param {Array} edges - 边数组
   * @param {Object} initialData - 初始数据
   * @returns {Promise<Object>} 执行结果
   */
  async executeFlow(nodes, edges, initialData = {}) {
    if (this.isExecuting) {
      throw new Error('流程正在执行中，请等待完成');
    }

    this.isExecuting = true;
    this.executionContext = { ...initialData };
    this.executionHistory = [];

    try {
      // 创建节点的深拷贝，避免修改原始数据
      const executionNodes = JSON.parse(JSON.stringify(nodes));
      const executionEdges = JSON.parse(JSON.stringify(edges));
      
      // 预构建执行图（一次性构建，避免重复计算）
      this.buildExecutionGraph(executionNodes, executionEdges);
      
      // 执行流程
      const result = await this.executeGraph();
      
      return {
        success: true,
        result: result,
        history: this.executionHistory,
        context: this.executionContext
      };
    } catch (error) {
      return {
        success: false,
        error: error.message,
        history: this.executionHistory,
        context: this.executionContext
      };
    } finally {
      this.isExecuting = false;
    }
  }

  /**
   * 预构建执行图（一次性构建，避免重复计算）
   * @param {Array} nodes - 节点数组
   * @param {Array} edges - 边数组
   */
  buildExecutionGraph(nodes, edges) {
    // 构建节点映射
    this.nodes = new Map(nodes.map(node => [node.id, node]));
    
    // 构建边映射
    this.edges = edges;
    
    // 预构建条件分支映射（O(n)时间复杂度）
    this.conditionNodes.clear();
    this.executionPaths.clear();
    
    for (const edge of edges) {
      const sourceNode = this.nodes.get(edge.source);
      const targetNode = this.nodes.get(edge.target);
      
      if (sourceNode?.type === 'condition_check') {
        // 初始化条件节点
        if (!this.conditionNodes.has(edge.source)) {
          this.conditionNodes.set(edge.source, {
            truePath: new Set(),
            falsePath: new Set(),
            mainPath: new Set()  // 新增主流程路径
          });
        }
        
        const conditionNode = this.conditionNodes.get(edge.source);
        if (edge.sourceHandle === 'true_output') {
          conditionNode.truePath.add(edge.target);
        } else if (edge.sourceHandle === 'false_output') {
          conditionNode.falsePath.add(edge.target);
        } else if (edge.sourceHandle === 'output') {
          conditionNode.mainPath.add(edge.target);  // 主流程路径
        }
      }
    }
    
    // 构建拓扑排序（一次性计算）
    this.executionOrder = this.topologicalSort();
  }

  /**
   * 拓扑排序（使用新的数据结构）
   * @returns {Array} 执行顺序
   */
  topologicalSort() {
    // 构建依赖关系映射
    const dependencies = new Map();
    const inDegree = new Map();
    
    // 初始化
    for (const nodeId of this.nodes.keys()) {
      dependencies.set(nodeId, []);
      inDegree.set(nodeId, 0);
    }
    
    // 构建依赖关系
    for (const edge of this.edges) {
      const sourceId = edge.source;
      const targetId = edge.target;
      
      if (dependencies.has(targetId)) {
        dependencies.get(targetId).push(sourceId);
        inDegree.set(targetId, inDegree.get(targetId) + 1);
      }
    }
    
    // 执行拓扑排序
    const queue = [];
    const result = [];
    
    // 找到所有入度为0的节点
    for (const [nodeId, degree] of inDegree) {
      if (degree === 0) {
        queue.push(nodeId);
      }
    }
    
    while (queue.length > 0) {
      const nodeId = queue.shift();
      result.push(nodeId);
      
      // 更新依赖节点的入度
      for (const [depNodeId, deps] of dependencies) {
        if (deps.includes(nodeId)) {
          const newDegree = inDegree.get(depNodeId) - 1;
          inDegree.set(depNodeId, newDegree);
          if (newDegree === 0) {
            queue.push(depNodeId);
          }
        }
      }
    }
    
    // 检查是否有环
    if (result.length !== this.nodes.size) {
      throw new Error('流程中存在循环依赖');
    }
    
    return result;
  }

  /**
   * 执行图（使用预构建的路径映射）
   * @returns {Promise<Object>} 执行结果
   */
  async executeGraph() {
    const context = { 
      node_results: {},
      flow_id: this.executionContext.agent_name
    };
    
    const results = {};
    const executedNodes = new Set();
    
    // 按拓扑排序执行节点
    for (const nodeId of this.executionOrder) {
      const node = this.nodes.get(nodeId);
      
      // 检查节点是否应该被执行（O(1)时间复杂度）
      if (!this.shouldExecuteNode(node, context, executedNodes)) {
        continue;
      }
      
      // 执行节点
      const result = await this.executeNode(node, context);
      results[nodeId] = result;
      context.node_results[nodeId] = result;
      executedNodes.add(nodeId);
      
      // 记录执行历史
      this.recordExecutionHistory(node, result);
    }
    
    return results;
  }





  /**
   * 判断节点是否应该被执行（O(1)时间复杂度）
   * @param {Object} node - 节点对象
   * @param {Object} context - 执行上下文
   * @param {Set} executedNodes - 已执行节点集合
   * @returns {boolean} 是否应该执行
   */
  shouldExecuteNode(node, context, executedNodes) {
    // 如果节点已经执行过，跳过
    if (executedNodes.has(node.id)) {
      return false;
    }
    
    // 检查是否被条件判断节点控制
    for (const [conditionId, paths] of this.conditionNodes) {
      if (paths.truePath.has(node.id) || paths.falsePath.has(node.id) || paths.mainPath.has(node.id)) {
        const conditionResult = context.node_results[conditionId];
        
        // 主流程路径的节点总是执行
        if (paths.mainPath.has(node.id)) {
          return true;
        }
        
        if (conditionResult?.condition_met !== undefined) {
          // 根据条件结果决定是否执行
          const shouldExecute = paths.truePath.has(node.id) 
            ? conditionResult.condition_met 
            : !conditionResult.condition_met;
          
          if (!shouldExecute) {
            return false;
          }
        }
      }
    }
    
    return true;
  }

  /**
   * 执行单个节点
   * @param {Object} node - 节点对象
   * @param {Object} context - 执行上下文
   * @returns {Promise<Object>} 执行结果
   */
  async executeNode(node, context) {
    node.status = 'executing';
    this.updateNodeStatus(node.id, 'executing');
    
    try {
      // 构建节点输入
      const nodeInputs = this.buildNodeInputs(node, context);
      const config = this.buildNodeConfig(node);
      
      // 直接在context中加入当前节点ID和流程数据
      context.current_node_id = node.id;
      context.flow_data = {
        nodes: Array.from(this.nodes.values()),
        edges: this.edges
      };
      
      const response = await fetch(`/jingrow/nodes/${node.type}/execute`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ 
          context, 
          inputs: nodeInputs, 
          config 
        })
      });
      
      const resJson = await response.json();
      
      if (!resJson.success) {
        throw new Error(resJson.error || '节点执行失败');
      }
      
      // 更新节点状态
      node.status = 'success';
      node.result = resJson;
      this.updateNodeStatus(node.id, 'success');
      
      return resJson;
      
    } catch (error) {
      // 处理执行失败
      node.status = 'failed';
      node.error = error.message;
      this.updateNodeStatus(node.id, 'failed', error.message);
      throw error;
    }
  }

  /**
   * 构建节点输入（O(1)时间复杂度）
   * @param {Object} node - 节点对象
   * @param {Object} context - 执行上下文
   * @returns {Object} 节点输入
   */
  buildNodeInputs(node, context) {
    const inputs = {};
    
    if (node.data?.inputs) {
      for (const [key, ref] of Object.entries(node.data.inputs)) {
        inputs[key] = context.node_results[ref.from]?.[ref.field];
      }
    }
    
    return inputs;
  }

  /**
   * 构建节点配置
   * @param {Object} node - 节点对象
   * @returns {Object} 节点配置
   */
  buildNodeConfig(node) {
    const { inputs, config: nodeConfig = {}, ...rest } = node.data || {};
    return { ...nodeConfig, ...rest };
  }

  /**
   * 记录执行历史
   * @param {Object} node - 节点对象
   * @param {Object} result - 执行结果
   */
  recordExecutionHistory(node, result) {
    let nodeLabel = node.data?.label;
    if (!nodeLabel) {
      const metadata = getNodeMetadataByType(node.type);
      nodeLabel = metadata ? metadata.label : node.type;
    }
    
    this.executionHistory.push({
      nodeId: node.id,
      nodeType: node.type,
      nodeLabel: nodeLabel,
      status: 'success',
      result: result,
      timestamp: new Date().toISOString()
    });
  }

  /**
   * 构建节点上下文
   * @param {String} nodeId - 节点ID
   * @param {Object} graph - 执行图
   * @param {Object} results - 执行结果
   * @returns {Object} 节点上下文
   */
  buildNodeContext(nodeId, graph, results) {
    const context = {
      ...this.executionContext
    };

    // 添加依赖节点的结果
    const dependencies = graph.dependencies[nodeId] || [];
    dependencies.forEach(depNodeId => {
      const depResult = results[depNodeId];
      if (depResult && depResult.success) {
        const depNode = graph.nodes[depNodeId];
        context[depNode.type] = depResult.data;
      }
    });

    return context;
  }

  /**
   * 更新节点状态（用于UI更新）
   * @param {String} nodeId - 节点ID
   * @param {String} status - 状态
   * @param {String} error - 错误信息
   */
  updateNodeStatus(nodeId, status, error = null) {
    // 这里可以触发UI更新事件
    const event = new CustomEvent('nodeStatusUpdate', {
      detail: { nodeId, status, error }
    });
    window.dispatchEvent(event);
  }

  /**
   * 获取执行历史
   * @returns {Array} 执行历史
   */
  getExecutionHistory() {
    return this.executionHistory;
  }

  /**
   * 获取执行上下文
   * @returns {Object} 执行上下文
   */
  getExecutionContext() {
    return this.executionContext;
  }

  /**
   * 重置执行器
   */
  reset() {
    this.executionContext = {};
    this.executionHistory = [];
    this.isExecuting = false;
  }
}

// 创建全局执行器实例
export const flowExecutor = new FlowExecutor(); 