import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';

export interface PipelineStep {
  id: string;
  type: string;
  config: any;
  dependsOn: string[];
  status: 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED';
}

/**
 * [CORE_AUTO_08] 自愈式 Pipeline 步骤拓扑重构 (Topo Self-Healing)
 * @description 核心逻辑：在 Pipeline 步骤失效且重试无效时，自动寻找替代路径与补偿逻辑。
 * 能够根据当前的上下文状态（如：CRAWL 失败 -> 尝试 SEARCH_ENGINE_CRAWL；AI_OPTIMIZE 失败 -> 尝试 RULE_BASED_OPTIMIZE）。
 */
export class TopoSelfHealingService {
  /**
   * 尝试重构失效的 Pipeline 拓扑
   */
  static async attemptHeal(
    failedStep: PipelineStep,
    fullPipeline: PipelineStep[],
    tenantId?: string
  ): Promise<{ canHeal: boolean; newSteps?: PipelineStep[] }> {
    // Feature Flag Check
    if (!(await FeatureGovernanceService.isEnabled('CORE_AUTO_TOPO_HEALING', tenantId))) {
      return { canHeal: false };
    }

    logger.warn(`[TopoHealing] Attempting to heal failed step: ${failedStep.id} (${failedStep.type})`);

    // 1. 定义自愈策略库 (Healing Strategy Matrix)
    const strategies: Record<string, (step: PipelineStep) => PipelineStep[]> = {
      'CRAWL': (step) => [
        {
          ...step,
          id: `${step.id}_fallback_search`,
          type: 'SEARCH_ENGINE_CRAWL',
          config: { ...step.config, useSecondaryEngine: true },
          status: 'PENDING'
        }
      ],
      'AI_OPTIMIZE': (step) => [
        {
          ...step,
          id: `${step.id}_fallback_rule`,
          type: 'RULE_BASED_OPTIMIZE',
          config: { ...step.config, strategy: 'STRICT_ATTRIBUTES' },
          status: 'PENDING'
        }
      ],
      'MULTI_PUBLISH': (step) => [
        {
          ...step,
          id: `${step.id}_retry_sequential`,
          config: { ...step.config, concurrency: 1 }, // 降低并发重试
          status: 'PENDING'
        }
      ]
    };

    const strategy = strategies[failedStep.type];
    if (strategy) {
      const replacementSteps = strategy(failedStep);
      
      // 2. 更新依赖链
      // 将所有依赖 failedStep 的步骤改为依赖新步骤
      const healedPipeline = fullPipeline.map(s => {
        if (s.dependsOn.includes(failedStep.id)) {
          return {
            ...s,
            dependsOn: s.dependsOn.map(d => d === failedStep.id ? replacementSteps[replacementSteps.length - 1].id : d)
          };
        }
        return s;
      });

      logger.info(`[TopoHealing] Successfully re-routed pipeline for step ${failedStep.id}`);
      return { canHeal: true, newSteps: replacementSteps };
    }

    logger.error(`[TopoHealing] No healing strategy found for type: ${failedStep.type}`);
    return { canHeal: false };
  }
}
