import db from '../../config/database';
import { logger } from '../../utils/logger';
import { InventoryRLService, InventoryMetrics } from './InventoryRLService';
import { InventoryForecastService } from './InventoryForecastService';

export interface WarehouseStock {
  warehouseId: string;
  productId: string;
  currentStock: number;
  avgDailySales: number;
  holdingCostPerUnit: number;
  transferCostPerUnit: number; // 从该仓调出的单位成本
}

/**
 * [BIZ_INV_20] 强化学习驱动的全球库存平衡 (Global Inventory RL Optimizer)
 * @description 核心逻辑：自动决策全球多仓库存调拨，最小化总持仓成本与缺货损失。
 */
export class InventoryRLOptimizerService {
  private static readonly TRANSFER_SUGGESTION_TABLE = 'cf_inventory_transfer_suggestions';

  /**
   * 运行全球库存平衡引擎
   */
  static async balanceGlobalStock(tenantId: string, productId: string) {
    logger.info(`[InventoryRLOptimizer] Balancing global stock for product: ${productId}`);

    // 1. 获取该 SKU 在所有仓库的实时库存与销售速率
    const stocks: WarehouseStock[] = await db('cf_inventory')
      .where({ tenant_id: tenantId, product_id: productId })
      .select('warehouse_id', 'current_stock', 'avg_daily_sales', 'holding_cost', 'transfer_cost');

    if (stocks.length < 2) {
      logger.info(`[InventoryRLOptimizer] Product ${productId} only in ${stocks.length} warehouse. Skipping balancing.`);
      return null;
    }

    // 2. 识别“缺货风险仓” (Demand > Stock) 与“冗余仓” (Stock >> Demand)
    const demandRisks = stocks.filter(s => s.current_stock < s.avg_daily_sales * 7); // 7 天安全库存
    const surplusWarehouses = stocks.filter(s => s.current_stock > s.avg_daily_sales * 30); // 30 天冗余库存

    if (demandRisks.length === 0 || surplusWarehouses.length === 0) {
      logger.info(`[InventoryRLOptimizer] Global stock for ${productId} is balanced.`);
      return null;
    }

    const suggestions = [];

    // 3. 执行调拨决策 (RL Reward: -TransferCost + AvoidedStockoutCost - HoldingCostDiff)
    for (const risk of demandRisks) {
      for (const surplus of surplusWarehouses) {
        const transferQty = Math.min(
          surplus.current_stock - (surplus.avg_daily_sales * 14), // 至少留 14 天
          (risk.avg_daily_sales * 14) - risk.current_stock // 补到 14 天
        );

        if (transferQty <= 0) continue;

        const cost = transferQty * surplus.transferCostPerUnit;
        const reward = (transferQty * risk.avg_daily_sales * 10) - cost; // 简单 Reward 模型

        if (reward > 0) {
          const suggestion = {
            id: `TRANS-${productId}-${surplus.warehouseId}-${risk.warehouseId}-${Date.now()}`,
            tenant_id: tenantId,
            product_id: productId,
            from_warehouse_id: surplus.warehouseId,
            to_warehouse_id: risk.warehouseId,
            quantity: transferQty,
            estimated_cost: Number(cost.toFixed(2)),
            estimated_reward: Number(reward.toFixed(2)),
            status: 'SUGGESTED',
            created_at: new Date()
          };

          await db(this.TRANSFER_SUGGESTION_TABLE).insert(suggestion);
          suggestions.push(suggestion);
        }
      }
    }

    return suggestions;
  }

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.TRANSFER_SUGGESTION_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.TRANSFER_SUGGESTION_TABLE} table...`);
      await db.schema.createTable(this.TRANSFER_SUGGESTION_TABLE, (table) => {
        table.string('id', 128).primary();
        table.string('tenant_id', 64).notNullable().index();
        table.string('product_id', 128).notNullable().index();
        table.string('from_warehouse_id', 64).notNullable();
        table.string('to_warehouse_id', 64).notNullable();
        table.integer('quantity').notNullable();
        table.decimal('estimated_cost', 15, 2);
        table.decimal('estimated_reward', 15, 2);
        table.string('status', 32).defaultTo('SUGGESTED');
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['from_warehouse_id', 'to_warehouse_id']);
      });
    }
  }
}
