import db from '../../config/database';
import { logger } from '../../utils/logger';
import { InventoryRLService, ReplenishmentPolicy } from './InventoryRLService';
import { TradeService } from './TradeService';

export interface ForecastResult {
  productId: string;
  tenantId: string;
  avgDailySales7d: number;
  avgDailySales30d: number;
  forecastNext7d: number;
  confidenceScore: number;
  updatedAt: Date;
}

/**
 * [BIZ_INV_10] AGI 销量预测与智能补货建议 (Forecast & Replenish)
 * @description 核心逻辑：利用历史订单数据进行时间序列分析，预测未来销量，并联动 [InventoryRLService] 生成补货指令。
 */
export class InventoryForecastService {
  private static readonly FORECAST_TABLE = 'cf_inventory_forecasts';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.FORECAST_TABLE);
    if (!hasTable) {
      logger.info(`📦 Creating ${this.FORECAST_TABLE} table...`);
      await db.schema.createTable(this.FORECAST_TABLE, (table) => {
        table.string('productId', 64).notNullable();
        table.string('tenantId', 64).notNullable();
        table.decimal('avgDailySales7d', 10, 2);
        table.decimal('avgDailySales30d', 10, 2);
        table.decimal('forecastNext7d', 10, 2);
        table.decimal('confidenceScore', 5, 4);
        table.timestamp('updatedAt').defaultTo(db.fn.now());
        table.primary(['productId', 'tenantId']);
      });
    }
  }

  /**
   * 生成销量预测
   */
  static async generateForecast(tenantId: string, productId: string): Promise<ForecastResult> {
    logger.info(`[InventoryForecast] Generating forecast for Product: ${productId}, Tenant: ${tenantId}`);

    // 1. 获取过去 30 天订单量
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    const orders = await db('cf_consumer_orders')
      .where({ tenant_id: tenantId, product_id: productId })
      .andWhere('created_at', '>=', thirtyDaysAgo)
      .select('quantity', 'created_at');

    // 2. 计算 7d 和 30d 平均销量
    const sevenDaysAgo = new Date();
    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

    const sales7d = orders
      .filter(o => new Date(o.created_at) >= sevenDaysAgo)
      .reduce((sum, o) => sum + o.quantity, 0);
    const sales30d = orders.reduce((sum, o) => sum + o.quantity, 0);

    const avg7d = sales7d / 7;
    const avg30d = sales30d / 30;

    // 3. 简单预测逻辑 (加权平均 + 趋势分析)
    const trend = avg7d / (avg30d || 1);
    const forecastNext7d = avg7d * trend * 7;
    const confidenceScore = trend > 0.8 && trend < 1.2 ? 0.85 : 0.6;

    const forecast: ForecastResult = {
      productId,
      tenantId,
      avgDailySales7d: Number(avg7d.toFixed(2)),
      avgDailySales30d: Number(avg30d.toFixed(2)),
      forecastNext7d: Number(forecastNext7d.toFixed(2)),
      confidenceScore,
      updatedAt: new Date()
    };

    // 4. 持久化预测结果
    await db(this.FORECAST_TABLE)
      .insert(forecast)
      .onConflict(['productId', 'tenantId'])
      .merge();

    return forecast;
  }

  /**
   * 触发智能补货建议
   */
  static async processReplenishment(tenantId: string, productId: string) {
    logger.info(`[InventoryForecast] Processing replenishment for Product: ${productId}`);

    // 1. 获取最新预测
    const forecast = await this.generateForecast(tenantId, productId);

    // 2. 获取当前库存
    const inventory = await db('cf_inventory')
      .where({ tenant_id: tenantId, product_id: productId })
      .first();
    
    if (!inventory) {
      logger.warn(`[InventoryForecast] No inventory record for ${productId}. Skipping.`);
      return;
    }

    // 3. 调用 RL 优化补货策略
    const policy: ReplenishmentPolicy = await InventoryRLService.optimizePolicy({
      productId,
      currentStock: inventory.available_stock,
      avgDailySales: forecast.avgDailySales7d,
      leadTimeDays: 7, // 假设 7 天提前期
      stockoutCount: 0, // 暂定
      holdingCostPerUnit: 0.1
    });

    // [BIZ_INV_10] 优先处理销售速率 > 5件/日的 SKU
    if (forecast.avgDailySales7d < 5) {
      logger.info(`[InventoryForecast] SKU ${productId} sales velocity (${forecast.avgDailySales7d}) < 5. Skipping proactive replenishment.`);
      return;
    }

    // 4. 判断是否需要补货 (Current Stock <= Reorder Point)
    if (inventory.available_stock <= policy.reorderPoint) {
      logger.info(`[InventoryForecast] REPLENISHMENT TRIGGERED for ${productId}. Stock: ${inventory.available_stock}, ROP: ${policy.reorderPoint}`);
      
      // 5. 自动生成采购单 (PO)
      await TradeService.createPurchaseOrder({
        tenantId,
        productId,
        supplierId: 'AUTO_SUPPLIER', // 实际应联动 SourcingDomainService
        quantity: policy.orderQuantity,
        unitPrice: 10.0, // 模拟价格
        totalAmount: policy.orderQuantity * 10.0,
        traceId: `AUTO-REPL-${Date.now()}`
      });
    } else {
      logger.info(`[InventoryForecast] Stock level safe for ${productId}. No replenishment needed.`);
    }
  }
}
