import { Request, Response } from 'express';
import db from '../../config/database';
import { CostAttributionService } from '../../core/telemetry/CostAttributionService';
import { NLAuditService } from '../../core/telemetry/NLAuditService';
import { TracingTopoService } from '../../core/telemetry/TracingTopoService';
import { AutoRedTeamingService } from '../../services/AutoRedTeamingService';

export class AuditController {
  /**
   * [UX_DASH_03] 获取操作流水线日志 (Timeline)
   */
  static async getTimeline(req: Request, res: Response) {
    try {
      const { tenantId, shopId } = (req as any).traceContext;
      const { module, action, limit = 50, offset = 0 } = req.query;

      const query = db('cf_operation_log')
        .where({ tenant_id: tenantId });

      if (shopId) query.andWhere({ shop_id: shopId });
      if (module) query.andWhere({ module });
      if (action) query.andWhere({ action });

      const logs = await query
        .orderBy('created_at', 'desc')
        .limit(Number(limit))
        .offset(Number(offset));

      const total = await query.clone().clearSelect().count('* as count').first();

      res.json({
        success: true,
        data: {
          logs,
          total: total?.count || 0,
        }
      });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }

  /**
   * [BIZ_AUDIT_03] 获取租户安全审计与风险画像
   */
  static async getRiskProfile(req: Request, res: Response) {
    try {
      const { tenantId } = (req as any).traceContext;

      // 1. 聚合异常登录、越权尝试等风险事件
      const riskEvents = await db('cf_operation_log')
        .where({ tenant_id: tenantId, result: 'failed' })
        .whereIn('action', ['LOGIN_FAILED', 'UNAUTHORIZED_ACCESS', 'KILL_SWITCH_ACTIVATE'])
        .orderBy('created_at', 'desc')
        .limit(10);

      // 2. 计算实时安全分 (基于异常比例)
      const totalOps = await db('cf_operation_log').where({ tenant_id: tenantId }).count('* as count').first();
      const failedOps = await db('cf_operation_log').where({ tenant_id: tenantId, result: 'failed' }).count('* as count').first();
      
      const riskScore = totalOps?.count ? Math.max(0, 100 - (Number(failedOps?.count) / Number(totalOps?.count) * 500)) : 100;

      res.json({
        success: true,
        data: {
          riskScore: Math.round(riskScore),
          riskLevel: riskScore > 90 ? 'LOW' : riskScore > 70 ? 'MEDIUM' : 'HIGH',
          recentRiskEvents: riskEvents,
          complianceStatus: {
            gdpr: true,
            pci_dss: false,
            iat_v23: true
          }
        }
      });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }

  /**
   * [BIZ_AUDIT_11] 生成并运行红蓝对抗场景
   */
  static async runRedTeaming(req: Request, res: Response) {
    try {
      const { tenantId } = (req as any).traceContext;
      const { moduleName } = req.body;
      const scenarios = await AutoRedTeamingService.generateScenarios(moduleName, tenantId);
      
      // 模拟运行第一个场景
      const result = await AutoRedTeamingService.runSimulation(scenarios[0].scenarioId);
      
      res.json({ success: true, data: { scenarios, simulationResult: result } });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }

  /**
   * [CORE_LOG_05] 自然语言审计查询
   */
  static async queryNLAudit(req: Request, res: Response) {
    try {
      const { tenantId, userId } = (req as any).traceContext;
      const { question } = req.body;
      const result = await NLAuditService.queryAuditLogs({ question, tenantId, userId });
      res.json({ success: true, data: result });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }

  /**
   * [CORE_TELE_08] 获取 API 成本对齐账单
   */
  static async getCostBill(req: Request, res: Response) {
    try {
      const { tenantId } = (req as any).traceContext;
      const data = await CostAttributionService.getTenantBill(tenantId);
      res.json({ success: true, data });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }

  /**
   * [CORE_TELE_09] 获取实时分布式追踪拓扑
   */
  static async getTracingTopo(req: Request, res: Response) {
    try {
      const { tenantId } = (req as any).traceContext;
      const data = await TracingTopoService.getLiveTopo(tenantId);
      res.json({ success: true, data });
    } catch (err: any) {
      res.status(500).json({ success: false, error: err.message });
    }
  }
}
