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

export interface IntermodalRoute {
  method: 'SEA_TO_RAIL' | 'SEA_TO_AIR' | 'RAIL_TO_AIR' | 'TRUCK_TO_RAIL';
  estimatedCost: number;
  timeframeDays: number;
  routeDetails: string;
}

/**
 * [BIZ_LOG_50] 弹性多式联运自动对冲引擎 (Intermodal Failover)
 * @description 当全球主航道发生黑天鹅事件时，自动计算并执行多式联运切换（如海转铁），最小化时效延误。
 */
export class IntermodalFailoverService {
  private static readonly FAILOVER_LOG_TABLE = 'cf_intermodal_failover_logs';

  /**
   * 执行多式联运切换与成本对冲计算
   */
  static async calculateFailover(params: {
    tenantId: string;
    originalRouteId: string;
    currentLocation: string;
    destination: string;
    weight: number;
  }): Promise<IntermodalRoute[]> {
    logger.info(`[IntermodalFailover] Calculating failover routes for ${params.originalRouteId} at ${params.currentLocation}`);

    // 1. 模拟多式联运选项
    const routes: IntermodalRoute[] = [
      {
        method: 'SEA_TO_RAIL',
        estimatedCost: params.weight * 2.5,
        timeframeDays: 15,
        routeDetails: `From Port ${params.currentLocation} to Rail Terminal at ${params.destination}`
      },
      {
        method: 'SEA_TO_AIR',
        estimatedCost: params.weight * 12.0,
        timeframeDays: 5,
        routeDetails: `Bypass Port ${params.currentLocation} via Air Freight to ${params.destination}`
      }
    ];

    // 2. 选择最优路径 (基于 Time-Cost 权重)
    // 逻辑：如果延迟风险极高，优先考虑 SEA_TO_AIR
    const sorted = routes.sort((a, b) => a.estimatedCost - b.estimatedCost);

    // 3. 记录切换建议
    for (const route of sorted) {
      await db(this.FAILOVER_LOG_TABLE).insert({
        tenant_id: params.tenantId,
        original_route_id: params.originalRouteId,
        method: route.method,
        estimated_cost: route.estimatedCost,
        timeframe_days: route.timeframeDays,
        route_details: route.routeDetails,
        status: 'SUGGESTED',
        created_at: new Date()
      });
    }

    return sorted;
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.FAILOVER_LOG_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.FAILOVER_LOG_TABLE} table...`);
      await db.schema.createTable(this.FAILOVER_LOG_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable().index();
        table.string('original_route_id', 64).notNullable();
        table.string('method', 32).notNullable();
        table.decimal('estimated_cost', 15, 2);
        table.integer('timeframe_days');
        table.text('route_details');
        table.string('status', 32).defaultTo('SUGGESTED');
        table.timestamp('created_at').defaultTo(db.fn.now());
      });
    }
  }
}
