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

export interface RouteHealth {
  routeId: string;
  type: 'AIR' | 'SEA' | 'LAND' | 'RAIL';
  status: 'HEALTHY' | 'CONGESTED' | 'BLOCKED';
  avgLeadTime: number; // days
  costPerKg: number; // USD
  riskScore: number; // 0-100
}

/**
 * [BIZ_LOG_20] 全球动态路径对冲与风险熔断 (Global Route Failover Engine)
 * @description 核心逻辑：在黑天鹅事件发生时，自动切换最优路径并对冲物流成本上涨。
 */
export class DynamicRoutingFailoverService {
  private static readonly ROUTE_STATS_TABLE = 'cf_route_health_stats';
  private static readonly RISK_ALERTS_TABLE = 'cf_logistics_risk_alerts';

  /**
   * 计算最优路径并处理对冲
   */
  static async calculateOptimalRoute(params: {
    tenantId: string;
    origin: string;
    destination: string;
    weight: number;
    maxBudget?: number;
    maxLeadTime?: number;
  }) {
    logger.info(`[DynamicRouting] Finding optimal route for ${params.origin} -> ${params.destination}`);

    // 1. 获取所有可用路径及其当前健康状态
    const availableRoutes = await db(this.ROUTE_STATS_TABLE)
      .where({ origin: params.origin, destination: params.destination })
      .andWhere('status', '!=', 'BLOCKED');

    if (availableRoutes.length === 0) {
      logger.error(`[DynamicRouting] No available routes found for ${params.origin} -> ${params.destination}`);
      return null;
    }

    // 2. 检查拥堵情况 (联动 CongestionFailoverService)
    const routesWithFailover = await Promise.all(availableRoutes.map(async (route) => {
      const failover = await CongestionFailoverService.getFailoverAdvice({
        currentRouteId: route.routeId,
        targetPortId: route.destination_port_id,
        tenantId: params.tenantId
      });
      
      return {
        ...route,
        isCongested: failover.isCongested,
        congestionLevel: failover.congestionLevel,
        effectiveLeadTime: route.avg_lead_time + (failover.estimatedTimeDiff / 24),
        effectiveCost: route.cost_per_kg + (failover.costDiff / params.weight)
      };
    }));

    // 3. 排序算法 (优先考虑 RiskScore < 50, 然后按 Cost * Time 权重)
    const sortedRoutes = routesWithFailover.sort((a, b) => {
      if (a.risk_score !== b.risk_score) return a.risk_score - b.risk_score;
      const scoreA = a.effectiveCost * a.effectiveLeadTime;
      const scoreB = b.effectiveCost * b.effectiveLeadTime;
      return scoreA - scoreB;
    });

    const optimal = sortedRoutes[0];
    
    // 4. 成本对冲建议 (如果最优路径成本比基准高出 20%)
    const baselineCost = 5.0; // 模拟基准价
    if (optimal.effectiveCost > baselineCost * 1.2) {
      logger.warn(`[DynamicRouting] High cost detected for optimal route: $${optimal.effectiveCost}/kg. Recommending HEDGING.`);
      // 触发对冲逻辑：例如建议分拆包裹或切换至更慢但更稳的渠道
    }

    return {
      routeId: optimal.routeId,
      type: optimal.type,
      estimatedCost: Number((optimal.effectiveCost * params.weight).toFixed(2)),
      estimatedLeadTime: Number(optimal.effectiveLeadTime.toFixed(1)),
      riskLevel: optimal.risk_score > 70 ? 'CRITICAL' : (optimal.risk_score > 40 ? 'WARNING' : 'SAFE'),
      isFailoverTriggered: optimal.isCongested
    };
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasStatsTable = await db.schema.hasTable(this.ROUTE_STATS_TABLE);
    if (!hasStatsTable) {
      logger.info(`📦 Creating ${this.ROUTE_STATS_TABLE} table...`);
      await db.schema.createTable(this.ROUTE_STATS_TABLE, (table) => {
        table.string('routeId', 64).primary();
        table.string('origin', 64).notNullable();
        table.string('destination', 64).notNullable();
        table.string('destination_port_id', 64);
        table.string('type', 32); // AIR, SEA, etc.
        table.string('status', 32);
        table.decimal('avg_lead_time', 10, 2);
        table.decimal('cost_per_kg', 10, 2);
        table.integer('risk_score'); // 0-100
        table.timestamp('updated_at').defaultTo(db.fn.now());
        table.index(['origin', 'destination']);
      });
    }

    const hasAlertsTable = await db.schema.hasTable(this.RISK_ALERTS_TABLE);
    if (!hasAlertsTable) {
      logger.info(`📦 Creating ${this.RISK_ALERTS_TABLE} table...`);
      await db.schema.createTable(this.RISK_ALERTS_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64);
        table.string('route_id', 64);
        table.string('risk_type', 32); // WAR, STRIKE, WEATHER
        table.string('severity', 16); // CRITICAL, WARNING
        table.text('description');
        table.timestamp('created_at').defaultTo(db.fn.now());
      });
    }
  }
}
