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

export interface BehavioralRiskRecord {
  tenantId: string;
  riskScore: number;
  riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
  detectedAnomalies: string[];
  lastDetectedAt: Date;
}

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;
  }) {
    if (!(await FeatureGovernanceService.isEnabled('BIZ_GOV_BEHAVIORAL_RISK', params.tenantId))) {
      return;
    }

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

    try {
      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);

      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();

      if (nextLevel === 'CRITICAL') {
        await AGIKillSwitchService.trigger断路器(params.tenantId, 'BEHAVIORAL_RISK_CRITICAL');
      }
    } catch (error) {
      logger.error(`[BehavioralRisk] Failed to update risk: ${error}`);
    }
  }

  static async getRisk(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,
      detectedAnomalies: record.detected_anomalies ? JSON.parse(record.detected_anomalies) : [],
      lastDetectedAt: record.last_detected_at
    };
  }

  static async getRiskStatus(tenantId: string): Promise<{ riskLevel: string; riskScore: number; anomalies: string[] }> {
    const record = await this.getRisk(tenantId);
    if (!record) {
      return { riskLevel: 'LOW', riskScore: 0, anomalies: [] };
    }
    return {
      riskLevel: record.riskLevel,
      riskScore: record.riskScore,
      anomalies: record.detectedAnomalies
    };
  }

  private static calculateLevel(score: number): 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' {
    if (score >= 80) return 'CRITICAL';
    if (score >= 60) return 'HIGH';
    if (score >= 30) return 'MEDIUM';
    return 'LOW';
  }
}