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

export interface AnomalyReport {
  id?: number;
  tenantId: string;
  trackingNumber: string;
  carrier: string;
  anomalyType: 'DELAY' | 'LOST' | 'WRONG_DESTINATION' | 'STUCK';
  reason: string;
  severity: 'LOW' | 'MEDIUM' | 'HIGH';
  status: 'PENDING' | 'RESOLVED';
  timestamp: Date;
}

/**
 * [ERP_LOG_01] 物流轨迹全链路归一化监控 (Logistics Tracker)
 * @description 核心逻辑：自动识别「异常节点」并触发 `reportAnomaly`。
 * 监控全球物流轨迹，识别停滞、延时或投递错误，联动 `FailoverLogisticsService` 自动切换路由。
 */
export class LogisticsTrackerService {
  private static readonly ANOMALY_TABLE = 'cf_logistics_anomalies';

  /**
   * 初始化表结构
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.ANOMALY_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.ANOMALY_TABLE} table...`);
      await db.schema.createTable(this.ANOMALY_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('tracking_number', 64).notNullable();
        table.string('carrier', 32).notNullable();
        table.string('anomaly_type', 32).notNullable();
        table.string('reason', 255);
        table.string('severity', 16);
        table.string('status', 16).defaultTo('PENDING');
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['tenant_id', 'tracking_number', 'status']);
      });
      logger.info(`✅ Table ${this.ANOMALY_TABLE} created`);
    }
  }

  /**
   * 轨迹异常检测 (Anomaly Detection)
   */
  static async detectAnomaly(tenantId: string, trackingNumber: string, trackingEvents: any[]): Promise<AnomalyReport | null> {
    if (!(await FeatureGovernanceService.isEnabled('ERP_LOG_TRACKER', tenantId))) {
      return null;
    }

    logger.info(`[LogisticsTracker] Detecting anomalies for Tracking: ${trackingNumber}`);

    try {
      // 1. 停滞识别：若最后一条轨迹更新时间超过 48h
      const latestEvent = trackingEvents[trackingEvents.length - 1];
      const hoursSinceUpdate = (Date.now() - new Date(latestEvent.timestamp).getTime()) / 3600000;

      let anomalyType: AnomalyReport['anomalyType'] | null = null;
      let reason = '';
      let severity: AnomalyReport['severity'] = 'LOW';

      if (hoursSinceUpdate > 48) {
        anomalyType = 'STUCK';
        reason = `No update for ${hoursSinceUpdate.toFixed(1)} hours.`;
        severity = hoursSinceUpdate > 120 ? 'HIGH' : 'MEDIUM';
      }

      // 2. 识别投递错误 (简易模式匹配)
      const hasErrorKeywords = trackingEvents.some(e => /return|failed|undeliverable/i.test(e.message));
      if (hasErrorKeywords) {
        anomalyType = 'WRONG_DESTINATION';
        reason = 'Keywords detected: return, failed, or undeliverable.';
        severity = 'HIGH';
      }

      if (anomalyType) {
        const report: AnomalyReport = {
          tenantId,
          trackingNumber,
          carrier: latestEvent.carrier || 'UNKNOWN',
          anomalyType,
          reason,
          severity,
          status: 'PENDING',
          timestamp: new Date()
        };

        // 3. 持久化 (Zero-Mock Policy)
        await db(this.ANOMALY_TABLE).insert({
          tenant_id: report.tenantId,
          tracking_number: report.trackingNumber,
          carrier: report.carrier,
          anomaly_type: report.anomalyType,
          reason: report.reason,
          severity: report.severity,
          status: report.status,
          created_at: report.timestamp
        });

        return report;
      }

      return null;
    } catch (err: any) {
      logger.error(`[LogisticsTracker] Detection failed: ${err.message}`);
      return null;
    }
  }

  /**
   * 获取租户所有待处理异常
   */
  static async getPendingAnomalies(tenantId: string): Promise<AnomalyReport[]> {
    return db(this.ANOMALY_TABLE)
      .where({ tenant_id: tenantId, status: 'PENDING' })
      .orderBy('created_at', 'desc');
  }
}
