import db from '../config/database';
import { logger } from '../utils/logger';
import { DecisionExplainabilityEngine } from '../core/ai/DecisionExplainabilityEngine';
import { AdviceService } from '../domains/Strategy/AdviceService';

export interface SafetyStockResult {
  productId: string;
  currentStock: number;
  recommendedSafetyStock: number;
  reason: string;
}

/**
 * [BIZ_OPS_136] 大促期间库存安全水位预测 (Safety Stock)
 * @description 核心逻辑：基于历史大促（如 Black Friday, 11.11）的销售波峰，预测未来大促期间的 SKU 安全水位，并生成补货建议。
 */
export class StockPlannerService {
  private static readonly INVENTORY_AUDIT_TABLE = 'cf_inventory_audit';
  private static readonly ORDER_TABLE = 'cf_consumer_orders';

  /**
   * 初始化数据库表
   */
  static async initTable() {
    const hasTable = await db.schema.hasTable(this.INVENTORY_AUDIT_TABLE);
    if (!hasTable) {
      await db.schema.createTable(this.INVENTORY_AUDIT_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).index();
        table.string('product_id', 64).index();
        table.integer('current_stock');
        table.integer('suggested_stock');
        table.string('reason', 255);
        table.string('status', 32).defaultTo('PENDING_REVIEW');
        table.timestamp('created_at').defaultTo(db.fn.now());
      });
    }
  }

  /**
   * 计算商品在特定时间段内的日均销量
   */
  private static async calculateAvgDailySales(tenantId: string, productId: string, days: number): Promise<number> {
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - days);

    const result = await db(this.ORDER_TABLE)
      .where({ tenant_id: tenantId, status: 'PAID' })
      .where('created_at', '>=', startDate)
      .andWhereRaw('JSON_EXTRACT(items, "$[*].product_id") LIKE ?', [`%${productId}%`])
      .count('id as count')
      .first();

    const count = Number(result?.count || 0);
    return count / days;
  }

  /**
   * 计算历史销售波峰乘数
   */
  private static async calculatePeakMultiplier(tenantId: string, productId: string): Promise<number> {
    // 假设历史大促期间（如 11.11 或 Black Friday）的销量数据
    // 实际上我们可以查找历史上销量最高的几天与平时均值的比率
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    const normalAvg = await this.calculateAvgDailySales(tenantId, productId, 30);
    if (normalAvg === 0) return 3; // 默认值，如果没有历史数据

    const peakResult = await db(this.ORDER_TABLE)
      .where({ tenant_id: tenantId, status: 'PAID' })
      .andWhereRaw('JSON_EXTRACT(items, "$[*].product_id") LIKE ?', [`%${productId}%`])
      .select(db.raw('DATE(created_at) as order_date'))
      .count('id as daily_count')
      .groupBy('order_date')
      .orderBy('daily_count', 'desc')
      .first();

    const peakDailyCount = Number(peakResult?.daily_count || 0);
    const multiplier = peakDailyCount / normalAvg;

    return Math.max(multiplier, 2); // 至少预留 2 倍波峰
  }

  /**
   * 预测安全水位 (BIZ_OPS_136)
   */
  static async predictSafetyStock(tenantId: string, productId: string): Promise<any> {
    logger.info(`[StockPlanner] Predicting safety stock for Product: ${productId}, Tenant: ${tenantId}`);

    try {
      // 1. 获取商品当前库存
      const product = await db('cf_product').where({ id: productId, tenant_id: tenantId }).first();
      if (!product) {
        // [V30.0] 尝试根据 productId 查找 (可能是平台级 ID)
        const productByExtId = await db('cf_product').where({ productId: productId, tenant_id: tenantId }).first();
        if (!productByExtId) throw new Error('Product not found');
        productId = productByExtId.id; // 统一使用内部 ID
      }

      // 2. 真实波峰分析与日销计算
      const avgDailySales = await this.calculateAvgDailySales(tenantId, productId, 30);
      const peakMultiplier = await this.calculatePeakMultiplier(tenantId, productId);
      const leadTimeDays = product.lead_time || 7; // 如果没有配置则默认为 7 天
      
      const safetyStockNeeded = Math.ceil(avgDailySales * peakMultiplier * leadTimeDays);
      const currentStock = product.stock || 0;

      if (currentStock < safetyStockNeeded) {
        const reason = `[XAI] Predicted surge for upcoming peak. Current stock (${currentStock}) is below required safety level (${safetyStockNeeded}) based on ${peakMultiplier.toFixed(1)}x historical peak multiplier.`;
        
        // 3. 生成补货建议 (Suggestion-First) -> 统一至 AdviceService
        const suggestionId = await AdviceService.recordAdvice({
          tenantId,
          shopId: product.shop_id || 'DEFAULT',
          traceId: 'stock-planner-' + Date.now(),
          insight: {
            type: 'INVENTORY',
            title: `Safety Stock Warning: ${product.name}`,
            description: reason,
            impact: 'high',
            confidence: 0.9,
            suggestedAction: 'RESTOCK',
            metadata: { 
              productId, 
              currentStock, 
              restockQuantity: safetyStockNeeded - currentStock,
              suggestedPrice: product.costPrice || 0
            }
          }
        });

        // 4. [UX_XAI_01] 记录决策证据链
        await DecisionExplainabilityEngine.logDecision({
          tenantId,
          module: 'INVENTORY_PLANNING',
          resourceId: String(suggestionId),
          decisionType: 'SAFETY_STOCK_PREDICTION',
          causalChain: reason,
          factors: [
            { name: 'PeakMultiplier', value: peakMultiplier, weight: 0.5, impact: 'NEGATIVE' },
            { name: 'LeadTimeDays', value: leadTimeDays, weight: 0.3, impact: 'NEGATIVE' },
            { name: 'AvgDailySales', value: avgDailySales, weight: 0.2, impact: 'NEGATIVE' }
          ],
          traceId: 'stock-planner-' + Date.now()
        });

        return { 
          success: true, 
          suggestionId, 
          currentStock, 
          suggestedStock: safetyStockNeeded, 
          reason,
          status: 'PENDING_REVIEW' 
        };
      }

      return { success: true, message: 'Stock level is sufficient for the predicted peak' };
    } catch (err: any) {
      logger.error(`[StockPlanner][WARN] Prediction failed: ${err.message}`);
      return { success: false, error: err.message };
    }
  }
}
