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

export interface BehavioralRiskRecord {
  tenantId: string;
  riskScore: number; // 0-100 (越高越危险)
  riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
  detectedAnomalies: string[]; // 发现的异常点
  lastDetectedAt: Date;
}

/**
 * [BIZ_GOV_09] 租户行为风险评分与动态限制 (Behavioral Risk Scoring)
 * @description 核心逻辑：基于 AGI 实时分析租户的操作行为（如：异常高频 API 调用、
 * 尝试越权访问、爬虫被封率骤增、资金异常流转）。
 * 系统自动计算风险分，并根据分值动态调整租户的 API 配额、
 * AGI 推理优先级。当风险等级达到 CRITICAL 时，自动联动 [AGIKillSwitchService] 触发熔断。
 */
export class BehavioralRiskService {
  private static readonly RISK_TABLE = 'cf_tenant_behavioral_risks';

  /**
   * 初始化表结构
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.RISK_TABLE);
    if (!hasTable) {
      console.log(`📦 Creating ${this.RISK_TABLE} table...`);
      await db.schema.createTable(this.RISK_TABLE, (table) => {
        table.string('tenant_id', 64).primary();
        table.integer('risk_score').defaultTo(0);
        table.string('risk_level', 16).defaultTo('LOW');
        table.json('detected_anomalies');
        table.timestamp('last_detected_at').defaultTo(db.fn.now());
        table.timestamps(true, true);
      });
      console.log(`✅ Table ${this.RISK_TABLE} created`);
    }
  }

  /**
   * 记录并更新行为风险评分
   */
  static async updateRisk(params: {
    tenantId: string;
    anomaly: string;
    impact: number; // 对分值的影响
  }) {
    // Feature Flag Check
    if (!(await FeatureGovernanceService.isEnabled('BIZ_GOV_BEHAVIORAL_RISK', params.tenantId))) {
      return;
    }

    logger.warn(`[BehavioralRisk] Detecting anomaly for ${params.tenantId}: ${params.anomaly}`);

    try {
      // 1. 获取当前风险分
      const current = await db(this.RISK_TABLE).where({ tenant_id: params.tenantId }).first();
      const currentScore = current?.risk_score || 0;
      const currentAnomalies = current?.detected_anomalies ? JSON.parse(current.detected_anomalies) : [];

      const nextScore = Math.min(100, currentScore + params.impact);
      const nextLevel = this.calculateLevel(nextScore);
      const nextAnomalies = [...new Set([...currentAnomalies, params.anomaly])].slice(-10); // 保留最近 10 个

      // 2. 更新数据库
      await db(this.RISK_TABLE)
        .insert({
          tenant_id: params.tenantId,
          risk_score: nextScore,
          risk_level: nextLevel,
          detected_anomalies: JSON.stringify(nextAnomalies),
          last_detected_at: new Date()
        })
        .onConflict('tenant_id')
        .merge();

      // 3. 联动熔断逻辑
      if (nextLevel === 'CRITICAL') {
        logger.error(`[BehavioralRisk] CRITICAL risk detected for ${params.tenantId}. Triggering Kill-Switch.`);
        await AGIKillSwitchService.activate(params.tenantId, `Behavioral risk score reached CRITICAL: ${nextScore}. Last anomaly: ${params.anomaly}`);
      }

      logger.info(`[BehavioralRisk] Tenant ${params.tenantId} score updated to ${nextScore} (${nextLevel})`);
    } catch (err: any) {
      logger.error(`[BehavioralRisk] Failed to update risk score: ${err.message}`);
    }
  }

  /**
   * 根据评分计算等级
   */
  private static calculateLevel(score: number): BehavioralRiskRecord['riskLevel'] {
    if (score < 30) return 'LOW';
    if (score < 60) return 'MEDIUM';
    if (score < 85) return 'HIGH';
    return 'CRITICAL';
  }

  /**
   * 自动化异常模式识别 (BIZ_GOV_BEHAVIORAL_RISK)
   * @description 基于 AGI 对租户近期审计流水进行聚类与模式分析，识别潜在的账户劫持或恶意爬虫行为。
   */
  static async analyzePatterns(tenantId: string) {
    if (!(await FeatureGovernanceService.isEnabled('BIZ_GOV_BEHAVIORAL_RISK', tenantId))) {
      return;
    }

    try {
      // 1. 获取近期审计日志
      const logs = await db('cf_audit_log')
        .where({ tenant_id: tenantId })
        .orderBy('created_at', 'desc')
        .limit(100);

      if (logs.length < 10) return;

      // 2. 统计异常指标
      const failedActions = logs.filter(l => l.result === 'failed').length;
      const uniqueResources = new Set(logs.map(l => l.target_id)).size;
      const actionsPerMinute = logs.length / ( (logs[0].created_at - logs[logs.length-1].created_at) / 60000 || 1 );

      // 3. 模式匹配逻辑
      if (failedActions > 15) {
        await this.updateRisk({
          tenantId,
          anomaly: 'PATTERN_BRUTE_FORCE_DETECTED',
          impact: 25
        });
      }

      if (actionsPerMinute > 60) {
        await this.updateRisk({
          tenantId,
          anomaly: 'PATTERN_HIGH_FREQUENCY_SCRAPING',
          impact: 15
        });
      }

      if (uniqueResources > 80 && logs.length > 90) {
        await this.updateRisk({
          tenantId,
          anomaly: 'PATTERN_MASS_DATA_ENUMERATION',
          impact: 20
        });
      }
    } catch (err: any) {
      logger.error(`[BehavioralRisk] Pattern analysis failed: ${err.message}`);
    }
  }

  /**
   * 获取租户当前风险状态
   */
  static async getRiskStatus(tenantId: string): Promise<BehavioralRiskRecord | null> {
    const record = await db(this.RISK_TABLE).where({ tenant_id: tenantId }).first();
    if (!record) return null;

    return {
      tenantId: record.tenant_id,
      riskScore: record.risk_score,
      riskLevel: record.risk_level as any,
      detectedAnomalies: JSON.parse(record.detected_anomalies),
      lastDetectedAt: record.last_detected_at
    };
  }

  /**
   * 自动重置/衰减风险分 (模拟周期性运行)
   */
  static async decayRiskScores() {
    logger.info('[BehavioralRisk] Running periodic risk score decay...');
    // 逻辑：每 24 小时对所有非 0 风险分减少 5 分
    await db(this.RISK_TABLE)
      .where('risk_score', '>', 0)
      .decrement('risk_score', 5);
  }
}
