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

/**
 * [AUTO_SB_02] 沙盒执行 ROI 自动评估器 (ROI Evaluator)
 * @description 核心逻辑：在建议正式进入审批流前，通过沙盒执行结果自动回测。
 * 对比“建议前”与“模拟建议后”的利润率、库存周转等指标，生成量化的 AGI 收益评估报告。
 */
export class SandboxROIAdvisor {
  /**
   * 评估 AGI 建议的预期 ROI
   * @param tenantId 租户 ID
   * @param suggestionId 建议 ID
   * @param simulatedResult 沙盒执行后的模拟结果
   */
  static async evaluateROI(tenantId: string, suggestionId: string, simulatedResult: any): Promise<number> {
    logger.info(`[ROIAdvisor] Evaluating ROI for Suggestion: ${suggestionId}`);

    try {
      // 1. 获取建议关联的因果链数据
      const decisionLog = await DecisionExplainabilityEngine.getDecisionByResourceId(suggestionId);
      if (!decisionLog) {
        logger.warn(`[ROIAdvisor] No decision log found for suggestion ${suggestionId}, using default ROI.`);
        return 0;
      }

      // 2. 根据模块类型计算 ROI
      let estimatedRoi = 0;
      const module = decisionLog.module;

      switch (module) {
        case 'PRICING':
          // 调价建议 ROI = (新售价 - 采购价) * 预估销量 - (旧售价 - 采购价) * 预估销量
          estimatedRoi = this.calculatePricingROI(simulatedResult);
          break;
        case 'SOURCING':
          // 采购源切换 ROI = (旧采购价 - 新采购价) * 历史月均销量
          estimatedRoi = this.calculateSourcingROI(simulatedResult);
          break;
        case 'INVENTORY_PLANNING':
          // 库存建议 ROI = 避免缺货损失 = 预估日销 * 缺货天数 * 客单利润
          estimatedRoi = this.calculateInventoryROI(simulatedResult);
          break;
        default:
          estimatedRoi = 0;
      }

      // 3. 更新沙盒执行记录中的 ROI 字段
      await db('cf_sandbox_executions')
        .where({ suggestion_id: suggestionId, tenant_id: tenantId })
        .update({ estimated_roi: estimatedRoi });

      return estimatedRoi;
    } catch (err: any) {
      logger.error(`[ROIAdvisor] ROI evaluation failed: ${err.message}`);
      return 0;
    }
  }

  private static calculatePricingROI(result: any): number {
    // result 包含: { productId, oldPrice, newPrice, estimatedMonthlySales, purchaseCost }
    const { oldPrice, newPrice, estimatedMonthlySales, purchaseCost } = result;
    if (!oldPrice || !newPrice || !estimatedMonthlySales || !purchaseCost) return 0;
    
    const oldMargin = (oldPrice - purchaseCost) * estimatedMonthlySales;
    const newMargin = (newPrice - purchaseCost) * estimatedMonthlySales;
    
    return Number((newMargin - oldMargin).toFixed(2));
  }

  private static calculateSourcingROI(result: any): number {
    // result 包含: { productId, oldSourcingCost, newSourcingCost, avgMonthlySales }
    const { oldSourcingCost, newSourcingCost, avgMonthlySales } = result;
    if (!oldSourcingCost || !newSourcingCost || !avgMonthlySales) return 0;
    
    const savingsPerUnit = oldSourcingCost - newSourcingCost;
    return Number((savingsPerUnit * avgMonthlySales).toFixed(2));
  }

  private static calculateInventoryROI(result: any): number {
    // result 包含: { productId, currentStock, suggestedStock, dailySales, unitProfit }
    const { currentStock, suggestedStock, dailySales, unitProfit } = result;
    if (currentStock >= suggestedStock) return 0;
    
    const stockGap = suggestedStock - currentStock;
    const stockoutDaysAvoided = Math.min(30, stockGap / (dailySales || 1));
    
    // 避免的缺货损失 = 预估日销 * 避免的缺货天数 * 单位利润
    return Number((dailySales * stockoutDaysAvoided * unitProfit).toFixed(2));
  }
}
