import { Injectable, Logger } from '@nestjs/common';
import { Product, Sku, Return, Order } from '@prisma/client';
import { PrismaService } from '../../config/database';

interface SkuData {
  id: string;
  productId: string;
  sku: string;
  price: number;
  stock: number;
  attributes: Record<string, string>;
  createdAt: Date;
  updatedAt: Date;
}

interface ProductData {
  id: string;
  name: string;
  description: string;
  category: string;
  brand: string;
  createdAt: Date;
  updatedAt: Date;
}

interface OptimizationResult {
  skuId: string;
  productName: string;
  currentReturnRate: number;
  targetReturnRate: number;
  optimizationStrategies: {
    type: string;
    description: string;
    expectedImpact: number; // 预期降低退货率的百分比
    priority: 'high' | 'medium' | 'low';
    implementationSteps: string[];
  }[];
  estimatedSavings: {
    returnReduction: number; // 预计减少的退货数量
    revenueImpact: number; // 预计增加的收入
    costSavings: number; // 预计节省的成本
  };
  confidence: number; // 优化方案的置信度
}

@Injectable()
export class ReturnOptimizationService {
  private readonly logger = new Logger(ReturnOptimizationService.name);

  constructor(private readonly prisma: PrismaService) {}

  /**
   * 为SKU生成智能优化建议
   * @param skuId SKU ID
   * @param traceId 链路追踪ID
   * @returns 优化建议结果
   */
  async generateOptimizationSuggestions(skuId: string, traceId: string): Promise<OptimizationResult> {
    this.logger.log(`开始为SKU生成优化建议: ${skuId}`, { traceId, skuId });

    try {
      // 获取SKU信息
      const sku = await this.prisma.sku.findUnique({
        where: { id: skuId },
        include: {
          product: true,
        },
      });

      if (!sku) {
        throw new Error(`SKU不存在: ${skuId}`);
      }

      // 获取SKU的退货数据
      const returns = await this.prisma.return.findMany({
        where: { skuId },
      });

      // 获取SKU的订单数据
      const orders = await this.prisma.order.findMany({
        where: {
          items: {
            some: {
              skuId,
            },
          },
        },
      });

      // 计算当前退货率
      const totalOrders = orders.length;
      const totalReturns = returns.length;
      const currentReturnRate = totalOrders > 0 ? (totalReturns / totalOrders) * 100 : 0;

      // 分析退货原因
      const returnReasons = this.analyzeReturnReasons(returns);

      // 生成优化策略
      const optimizationStrategies = this.generateOptimizationStrategies({
        sku,
        product: sku.product,
        returnReasons,
        currentReturnRate,
      });

      // 计算预计节省
      const estimatedSavings = this.calculateEstimatedSavings({
        sku,
        currentReturnRate,
        optimizationStrategies,
        orders,
      });

      // 计算置信度
      const confidence = this.calculateConfidence(optimizationStrategies, returnReasons);

      // 设置目标退货率
      const targetReturnRate = Math.max(0, currentReturnRate - 5); // 目标降低5个百分点

      const result: OptimizationResult = {
        skuId,
        productName: sku.product.name,
        currentReturnRate: Math.round(currentReturnRate * 100) / 100,
        targetReturnRate: Math.round(targetReturnRate * 100) / 100,
        optimizationStrategies,
        estimatedSavings,
        confidence,
      };

      this.logger.log(`SKU优化建议生成完成: ${skuId}`, { traceId, result });

      return result;
    } catch (error) {
      this.logger.error(`SKU优化建议生成失败: ${error.message}`, { traceId, skuId, error });
      throw error;
    }
  }

  /**
   * 批量为SKU生成优化建议
   * @param skuIds SKU ID列表
   * @param traceId 链路追踪ID
   * @returns 优化建议结果列表
   */
  async batchGenerateOptimizationSuggestions(skuIds: string[], traceId: string): Promise<OptimizationResult[]> {
    this.logger.log(`开始批量为SKU生成优化建议, 数量: ${skuIds.length}`, { traceId });

    const results: OptimizationResult[] = [];

    for (const skuId of skuIds) {
      try {
        const result = await this.generateOptimizationSuggestions(skuId, traceId);
        results.push(result);
      } catch (error) {
        this.logger.error(`批量生成SKU优化建议失败: ${skuId}, 错误: ${error.message}`, { traceId, skuId });
      }
    }

    this.logger.log(`批量生成SKU优化建议完成, 成功: ${results.length}/${skuIds.length}`, { traceId });

    return results;
  }

  /**
   * 分析退货原因
   */
  private analyzeReturnReasons(returns: Return[]): Record<string, number> {
    const reasonCounts = new Map<string, number>();

    returns.forEach(ret => {
      const reason = ret.reason || '其他';
      reasonCounts.set(reason, (reasonCounts.get(reason) || 0) + 1);
    });

    return Object.fromEntries(reasonCounts);
  }

  /**
   * 生成优化策略
   */
  private generateOptimizationStrategies(data: {
    sku: Sku & { product: Product };
    product: Product;
    returnReasons: Record<string, number>;
    currentReturnRate: number;
  }): OptimizationResult['optimizationStrategies'] {
    const strategies: OptimizationResult['optimizationStrategies'] = [];

    // 基于退货原因的策略
    const topReasons = Object.entries(data.returnReasons)
      .sort(([,a], [,b]) => b - a)
      .slice(0, 3); // 取前3个主要原因

    topReasons.forEach(([reason, count]) => {
      switch (reason) {
        case '质量问题':
          strategies.push({
            type: 'quality_improvement',
            description: '改进产品质量，加强质量控制',
            expectedImpact: 15,
            priority: 'high',
            implementationSteps: [
              '对供应商进行审核和评估',
              '建立质量检测流程',
              '对不合格产品进行召回',
              '定期抽样检查',
            ],
          });
          break;
        case '尺寸不符':
          strategies.push({
            type: 'size_accuracy',
            description: '提供更准确的尺寸信息和测量指南',
            expectedImpact: 10,
            priority: 'medium',
            implementationSteps: [
              '更新产品页面的尺寸表',
              '提供详细的测量方法',
              '添加尺寸对比图表',
              '收集客户反馈优化尺寸描述',
            ],
          });
          break;
        case '描述不符':
          strategies.push({
            type: 'description_accuracy',
            description: '优化产品描述和图片，确保与实际产品一致',
            expectedImpact: 12,
            priority: 'high',
            implementationSteps: [
              '更新产品描述，确保准确性',
              '添加更多真实产品图片',
              '拍摄产品使用视频',
              '明确标注产品的材质和特性',
            ],
          });
          break;
        case '物流损坏':
          strategies.push({
            type: 'packaging_improvement',
            description: '优化包装，减少物流损坏',
            expectedImpact: 8,
            priority: 'medium',
            implementationSteps: [
              '使用更坚固的包装材料',
              '添加缓冲材料',
              '选择更可靠的物流服务商',
              '在包装上标注易碎标志',
            ],
          });
          break;
        case '其他':
          strategies.push({
            type: 'customer_feedback',
            description: '收集更详细的客户反馈，了解具体问题',
            expectedImpact: 5,
            priority: 'low',
            implementationSteps: [
              '添加详细的退货原因调查',
              '主动联系退货客户了解原因',
              '建立客户反馈收集系统',
              '定期分析反馈数据',
            ],
          });
          break;
      }
    });

    // 通用优化策略
    if (data.currentReturnRate > 15) {
      strategies.push({
        type: 'pricing_strategy',
        description: '调整定价策略，提高产品价值感知',
        expectedImpact: 7,
        priority: 'medium',
        implementationSteps: [
          '分析竞争对手定价',
          '调整产品定价',
          '提供捆绑销售选项',
          '推出限时优惠活动',
        ],
      });
    }

    // 产品信息优化
    strategies.push({
      type: 'product_information',
      description: '优化产品页面信息，提高透明度',
      expectedImpact: 6,
      priority: 'low',
      implementationSteps: [
        '添加详细的产品规格',
        '提供真实的客户评价',
        '更新产品使用说明',
        '添加常见问题解答',
      ],
    });

    // 客户服务优化
    strategies.push({
      type: 'customer_service',
      description: '提升客户服务质量，减少沟通误解',
      expectedImpact: 4,
      priority: 'low',
      implementationSteps: [
        '提供更及时的客户支持',
        '培训客服人员产品知识',
        '建立快速响应机制',
        '主动解决客户问题',
      ],
    });

    // 按优先级排序
    strategies.sort((a, b) => {
      const priorityOrder = { high: 3, medium: 2, low: 1 };
      return priorityOrder[b.priority] - priorityOrder[a.priority];
    });

    return strategies;
  }

  /**
   * 计算预计节省
   */
  private calculateEstimatedSavings(data: {
    sku: Sku;
    currentReturnRate: number;
    optimizationStrategies: OptimizationResult['optimizationStrategies'];
    orders: Order[];
  }): OptimizationResult['estimatedSavings'] {
    // 计算总预期影响
    const totalExpectedImpact = data.optimizationStrategies
      .reduce((sum, strategy) => sum + strategy.expectedImpact, 0);

    // 计算预计减少的退货率
    const expectedReturnRateReduction = Math.min(totalExpectedImpact, data.currentReturnRate);

    // 计算预计减少的退货数量
    const averageMonthlyOrders = orders.length / 3; // 假设数据覆盖3个月
    const returnReduction = (averageMonthlyOrders * expectedReturnRateReduction) / 100;

    // 计算预计增加的收入（假设退货商品无法再次销售）
    const revenueImpact = returnReduction * data.sku.price;

    // 计算预计节省的成本（退货处理成本）
    const averageReturnProcessingCost = 20; // 假设每笔退货处理成本为20元
    const costSavings = returnReduction * averageReturnProcessingCost;

    return {
      returnReduction: Math.round(returnReduction),
      revenueImpact: Math.round(revenueImpact * 100) / 100,
      costSavings: Math.round(costSavings * 100) / 100,
    };
  }

  /**
   * 计算置信度
   */
  private calculateConfidence(
    strategies: OptimizationResult['optimizationStrategies'],
    returnReasons: Record<string, number>
  ): number {
    // 基于策略数量和退货原因分析的完整性计算置信度
    const strategyCount = strategies.length;
    const reasonCount = Object.keys(returnReasons).length;

    // 基础置信度
    let baseConfidence = 70;

    // 根据策略数量调整
    if (strategyCount >= 5) {
      baseConfidence += 10;
    } else if (strategyCount >= 3) {
      baseConfidence += 5;
    }

    // 根据退货原因分析调整
    if (reasonCount >= 3) {
      baseConfidence += 10;
    } else if (reasonCount >= 2) {
      baseConfidence += 5;
    }

    // 最高置信度为95%
    return Math.min(95, baseConfidence);
  }

  /**
   * 获取优化建议报告
   * @param skuIds SKU ID列表
   * @param traceId 链路追踪ID
   * @returns 优化建议报告
   */
  async getOptimizationReport(skuIds: string[], traceId: string) {
    this.logger.log(`生成优化建议报告, SKU数量: ${skuIds.length}`, { traceId });

    try {
      // 批量生成优化建议
      const optimizationResults = await this.batchGenerateOptimizationSuggestions(skuIds, traceId);

      // 计算整体统计数据
      const totalCurrentReturnRate = optimizationResults.reduce((sum, result) => sum + result.currentReturnRate, 0) / optimizationResults.length;
      const totalTargetReturnRate = optimizationResults.reduce((sum, result) => sum + result.targetReturnRate, 0) / optimizationResults.length;
      const totalReturnReduction = optimizationResults.reduce((sum, result) => sum + result.estimatedSavings.returnReduction, 0);
      const totalRevenueImpact = optimizationResults.reduce((sum, result) => sum + result.estimatedSavings.revenueImpact, 0);
      const totalCostSavings = optimizationResults.reduce((sum, result) => sum + result.estimatedSavings.costSavings, 0);

      // 分析策略分布
      const strategyDistribution = new Map<string, number>();
      optimizationResults.forEach(result => {
        result.optimizationStrategies.forEach(strategy => {
          strategyDistribution.set(strategy.type, (strategyDistribution.get(strategy.type) || 0) + 1);
        });
      });

      // 按优先级统计策略
      const priorityDistribution = new Map<string, number>();
      optimizationResults.forEach(result => {
        result.optimizationStrategies.forEach(strategy => {
          priorityDistribution.set(strategy.priority, (priorityDistribution.get(strategy.priority) || 0) + 1);
        });
      });

      const report = {
        skuCount: optimizationResults.length,
        averageCurrentReturnRate: Math.round(totalCurrentReturnRate * 100) / 100,
        averageTargetReturnRate: Math.round(totalTargetReturnRate * 100) / 100,
        totalReturnReduction: Math.round(totalReturnReduction),
        totalRevenueImpact: Math.round(totalRevenueImpact * 100) / 100,
        totalCostSavings: Math.round(totalCostSavings * 100) / 100,
        strategyDistribution: Object.fromEntries(strategyDistribution),
        priorityDistribution: Object.fromEntries(priorityDistribution),
        optimizationResults,
        topRecommendations: this.getTopRecommendations(optimizationResults),
      };

      this.logger.log(`生成优化建议报告完成`, { traceId, report });

      return report;
    } catch (error) {
      this.logger.error(`生成优化建议报告失败: ${error.message}`, { traceId, error });
      throw error;
    }
  }

  /**
   * 获取顶级建议
   */
  private getTopRecommendations(optimizationResults: OptimizationResult[]): Array<{
    strategyType: string;
    description: string;
    frequency: number;
    averageImpact: number;
  }> {
    const strategyStats = new Map<string, { count: number; totalImpact: number; description: string }>();

    optimizationResults.forEach(result => {
      result.optimizationStrategies.forEach(strategy => {
        if (!strategyStats.has(strategy.type)) {
          strategyStats.set(strategy.type, { count: 0, totalImpact: 0, description: strategy.description });
        }
        const stats = strategyStats.get(strategy.type)!;
        stats.count++;
        stats.totalImpact += strategy.expectedImpact;
      });
    });

    return Array.from(strategyStats.entries())
      .map(([type, stats]) => ({
        strategyType: type,
        description: stats.description,
        frequency: stats.count,
        averageImpact: Math.round((stats.totalImpact / stats.count) * 100) / 100,
      }))
      .sort((a, b) => b.frequency - a.frequency)
      .slice(0, 5);
  }

  /**
   * 应用优化策略
   * @param skuId SKU ID
   * @param strategyType 策略类型
   * @param traceId 链路追踪ID
   * @returns 应用结果
   */
  async applyOptimizationStrategy(skuId: string, strategyType: string, traceId: string) {
    this.logger.log(`应用优化策略: ${strategyType} 到 SKU: ${skuId}`, { traceId, skuId, strategyType });

    try {
      // 这里可以实现具体的策略应用逻辑
      // 例如：更新产品信息、调整定价、优化包装等

      // 模拟应用结果
      const result = {
        skuId,
        strategyType,
        applied: true,
        message: `成功应用 ${strategyType} 策略到 SKU ${skuId}`,
        timestamp: new Date(),
      };

      this.logger.log(`优化策略应用完成`, { traceId, result });

      return result;
    } catch (error) {
      this.logger.error(`应用优化策略失败: ${error.message}`, { traceId, skuId, strategyType, error });
      throw error;
    }
  }
}
