import db from '../config/database';
import { logger } from '../utils/logger';
import { DecisionExplainabilityEngine } from '../core/ai/DecisionExplainabilityEngine';

/**
 * [BIZ_OPS_134] 虚假单号轨迹识别模型 (Fake Tracking)
 * @description 核心逻辑：分析物流轨迹中的“时空矛盾”（如 1 小时跨越 1000 公里），自动识别虚假单号并生成风控建议。
 */
export class TrackingFraudDetector {
  private static readonly FRAUD_AUDIT_TABLE = 'cf_logistic_fraud_audit';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.FRAUD_AUDIT_TABLE);
    if (!hasTable) {
      await db.schema.createTable(this.FRAUD_AUDIT_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).index();
        table.string('tracking_number', 128).index();
        table.string('anomaly_type', 64); // e.g., IMPOSSIBLE_TRAVEL
        table.text('evidence');
        table.string('status', 32).defaultTo('PENDING_REVIEW');
        table.timestamp('created_at').defaultTo(db.fn.now());
      });
    }
  }

  /**
   * 分析轨迹异常 (BIZ_OPS_134)
   */
  static async analyzeTrackingAnomaly(tenantId: string, trackingNumber: string): Promise<any> {
    logger.info(`[TrackingFraud] Analyzing tracking: ${trackingNumber} for Tenant: ${tenantId}`);

    try {
      // 1. 获取该单号的所有轨迹点
      const points = await db('cf_logistic_telemetry')
        .where({ trackingNumber })
        .orderBy('timestamp', 'asc');

      if (points.length < 2) return { success: true, isFraud: false };

      // 2. 时空矛盾分析 (Impossible Travel)
      for (let i = 1; i < points.length; i++) {
        const p1 = points[i - 1];
        const p2 = points[i];

        // 如果轨迹点包含经纬度，计算距离
        if (p1.location && p2.location && p1.timestamp && p2.timestamp) {
          // 模拟逻辑：如果两个点在不同城市，但时间间隔极短
          const timeDiffHours = (new Date(p2.timestamp).getTime() - new Date(p1.timestamp).getTime()) / (1000 * 3600);
          
          // 假设：1 小时内跨越不同城市（如上海到北京）则视为异常
          if (timeDiffHours < 1 && p1.location !== p2.location && !p2.location.includes(p1.location)) {
            const reason = `Impossible travel detected: Moved from ${p1.location} to ${p2.location} in ${timeDiffHours.toFixed(2)}h.`;
            
            // 3. 记录风控建议
            const [suggestionId] = await db(this.FRAUD_AUDIT_TABLE).insert({
              tenant_id: tenantId,
              tracking_number: trackingNumber,
              anomaly_type: 'IMPOSSIBLE_TRAVEL',
              evidence: reason,
              status: 'PENDING_REVIEW',
              created_at: new Date()
            });

            // 4. [UX_XAI_01] 记录决策证据链
            await DecisionExplainabilityEngine.logDecision({
              tenantId,
              module: 'LOGISTICS_FRAUD',
              resourceId: String(suggestionId),
              decisionType: 'FAKE_TRACKING_DETECTION',
              causalChain: reason,
              factors: [
                { name: 'TimeDifference', value: timeDiffHours, weight: 0.6, impact: 'NEGATIVE' },
                { name: 'LocationChange', value: `${p1.location} -> ${p2.location}`, weight: 0.4, impact: 'NEGATIVE' }
              ],
              traceId: 'fraud-detect-' + Date.now()
            });

            return { success: true, isFraud: true, suggestionId, reason };
          }
        }
      }

      return { success: true, isFraud: false };
    } catch (err: any) {
      logger.error(`[TrackingFraud][WARN] Detection failed: ${err.message}`);
      return { success: false, error: err.message };
    }
  }
}
