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

export interface HealthPrediction {
  metric: string;
  currentValue: number;
  predictedValue: number;
  threshold: number;
  probabilityOfFailure: number; // 0-1
  estimatedTimeUntilBreach: number; // minutes
  suggestedAction: string;
}

/**
 * [CORE_TELE_02] 预测性系统健康度看板 (Predictive Health)
 * @description 利用 AI 预测未来 24h 潜在瓶颈（如数据库连接耗尽、Redis 内存溢出、API 延迟激增）。
 * 遵循 V30.0 Zero-Mock 规范，基于真实遥测数据进行趋势分析。
 */
export class PredictiveHealthService {
  private static readonly PREDICTION_TABLE = 'cf_telemetry_predictions';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.PREDICTION_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.PREDICTION_TABLE} table...`);
      await db.schema.createTable(this.PREDICTION_TABLE, (table) => {
        table.increments('id').primary();
        table.string('metric', 64).notNullable();
        table.float('current_value').notNullable();
        table.float('predicted_value').notNullable();
        table.float('threshold').notNullable();
        table.float('probability_of_failure').notNullable();
        table.integer('estimated_time_until_breach').notNullable();
        table.text('suggested_action').notNullable();
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['metric', 'created_at']);
      });
      logger.info(`✅ Table ${this.PREDICTION_TABLE} created`);
    }
  }

  /**
   * 获取系统健康度预测结果
   */
  static async getHealthPredictions(tenantId?: string): Promise<HealthPrediction[]> {
    // Feature Flag Check
    if (!(await FeatureGovernanceService.isEnabled('CORE_TELE_PREDICTIVE_HEALTH', tenantId))) {
      return [];
    }

    logger.info('[PredictiveHealth] Analyzing real-time system metrics for future bottlenecks...');

    const predictions: HealthPrediction[] = [];

    try {
      // 1. 数据库连接池分析
      const dbPool = (db.client as any).pool;
      const usedConns = dbPool?.used?.length || 0;
      const maxConns = dbPool?.max || 10;
      const dbUsage = (usedConns / maxConns) * 100;
      
      // 简单线性外推预测 (基于历史 1 小时趋势)
      const dbTrend = await this.calculateTrend('DB_CONNECTION_POOL');
      const predictedDbUsage = Math.min(100, dbUsage + (dbTrend * 24)); // 预测 24h 后

      predictions.push({
        metric: 'DB_CONNECTION_POOL',
        currentValue: Number(dbUsage.toFixed(2)),
        predictedValue: Number(predictedDbUsage.toFixed(2)),
        threshold: 90,
        probabilityOfFailure: predictedDbUsage > 90 ? 0.8 : 0.1,
        estimatedTimeUntilBreach: dbTrend > 0 ? Math.round((90 - dbUsage) / dbTrend) : -1,
        suggestedAction: predictedDbUsage > 90 ? 'Increase DB Pool Size or optimize long transactions.' : 'Healthy'
      });

      // 2. Redis 内存分析
      const redis = RedisService.getClient();
      const info = await redis.info('memory');
      const usedMemoryMatch = info.match(/used_memory:(\d+)/);
      const maxMemoryMatch = info.match(/maxmemory:(\d+)/);
      
      const usedMem = usedMemoryMatch ? parseInt(usedMemoryMatch[1]) / 1024 / 1024 : 0; // MB
      const maxMem = maxMemoryMatch && parseInt(maxMemoryMatch[1]) > 0 
        ? parseInt(maxMemoryMatch[1]) / 1024 / 1024 
        : (os.totalmem() / 1024 / 1024) * 0.1; // 默认取系统内存 10%
      
      const memUsage = (usedMem / maxMem) * 100;
      const memTrend = await this.calculateTrend('REDIS_MEMORY_USAGE');
      const predictedMemUsage = Math.min(100, memUsage + (memTrend * 24));

      predictions.push({
        metric: 'REDIS_MEMORY_USAGE',
        currentValue: Number(memUsage.toFixed(2)),
        predictedValue: Number(predictedMemUsage.toFixed(2)),
        threshold: 85,
        probabilityOfFailure: predictedMemUsage > 85 ? 0.7 : 0.05,
        estimatedTimeUntilBreach: memTrend > 0 ? Math.round((85 - memUsage) / memTrend) : -1,
        suggestedAction: predictedMemUsage > 85 ? 'Enable Redis key eviction or upgrade memory quota.' : 'Healthy'
      });

      // 3. 系统负载分析
      const load = os.loadavg()[0];
      const cpuCores = os.cpus().length;
      const loadUsage = (load / cpuCores) * 100;
      const loadTrend = await this.calculateTrend('SYSTEM_LOAD');
      const predictedLoad = loadUsage + (loadTrend * 24);

      predictions.push({
        metric: 'SYSTEM_LOAD',
        currentValue: Number(loadUsage.toFixed(2)),
        predictedValue: Number(predictedLoad.toFixed(2)),
        threshold: 80,
        probabilityOfFailure: predictedLoad > 80 ? 0.6 : 0.1,
        estimatedTimeUntilBreach: loadTrend > 0 ? Math.round((80 - loadUsage) / loadTrend) : -1,
        suggestedAction: predictedLoad > 80 ? 'Scale out application nodes or check for CPU-intensive tasks.' : 'Healthy'
      });

      // 持久化预测结果 (Zero-Mock 落地)
      for (const p of predictions) {
        await this.logPrediction(p);
      }

    } catch (err: any) {
      logger.error(`[PredictiveHealth] Metric analysis failed: ${err.message}`);
    }

    return predictions;
  }

  /**
   * 基于历史数据计算指标变化趋势 (每小时变化率)
   */
  private static async calculateTrend(metric: string): Promise<number> {
    const history = await db(this.PREDICTION_TABLE)
      .where({ metric })
      .orderBy('created_at', 'desc')
      .limit(10);

    if (history.length < 2) return 0;

    const latest = history[0].current_value;
    const oldest = history[history.length - 1].current_value;
    const timeDiff = (new Date(history[0].created_at).getTime() - new Date(history[history.length - 1].created_at).getTime()) / 3600000; // hours

    return timeDiff > 0 ? (latest - oldest) / timeDiff : 0;
  }

  /**
   * 记录预测结果用于回溯
   */
  static async logPrediction(prediction: HealthPrediction) {
    await db(this.PREDICTION_TABLE).insert({
      metric: prediction.metric,
      current_value: prediction.currentValue,
      predicted_value: prediction.predictedValue,
      threshold: prediction.threshold,
      probability_of_failure: prediction.probabilityOfFailure,
      estimated_time_until_breach: prediction.estimatedTimeUntilBreach,
      suggested_action: prediction.suggestedAction,
      created_at: new Date()
    });
  }
}
