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

interface ReturnData {
  id: string;
  orderId: string;
  productId: string;
  skuId: string;
  reason: string;
  description: string;
  status: 'PENDING' | 'APPROVED' | 'REJECTED';
  createdAt: Date;
  updatedAt: Date;
}

interface ProductData {
  id: string;
  name: string;
  sku: string;
  category: string;
  price: number;
  createdAt: Date;
  updatedAt: Date;
}

interface ReturnAnalysisResult {
  skuId: string;
  productName: string;
  returnRate: number;
  totalReturns: number;
  totalOrders: number;
  primaryReasons: {
    reason: string;
    count: number;
    percentage: number;
  }[];
  temporalAnalysis: {
    period: string;
    returnRate: number;
    orderCount: number;
    returnCount: number;
  }[];
  recommendations: string[];
  riskLevel: 'low' | 'medium' | 'high';
}

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

  constructor(private readonly prisma: PrismaService) {}

  /**
   * 分析SKU退货原因
   * @param skuId SKU ID
   * @param traceId 链路追踪ID
   * @returns 退货分析结果
   */
  async analyzeReturnReasons(skuId: string, traceId: string): Promise<ReturnAnalysisResult> {
    this.logger.log(`开始分析SKU退货原因: ${skuId}`, { traceId, skuId });

    try {
      // 获取SKU相关的退货数据
      const returns = await this.prisma.return.findMany({
        where: { skuId },
        include: {
          order: {
            include: {
              product: true,
            },
          },
        },
      });

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

      // 获取商品信息
      const product = await this.prisma.product.findFirst({
        where: {
          skus: {
            some: {
              id: skuId,
            },
          },
        },
      });

      if (!product) {
        throw new Error(`SKU对应的商品不存在: ${skuId}`);
      }

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

      // 分析主要退货原因
      const primaryReasons = this.analyzePrimaryReasons(returns);

      // 时间趋势分析
      const temporalAnalysis = this.analyzeTemporalTrends(returns, orders);

      // 生成建议
      const recommendations = this.generateRecommendations({
        returnRate,
        primaryReasons,
        temporalAnalysis,
        product,
      });

      // 评估风险等级
      const riskLevel = this.assessRiskLevel(returnRate);

      const result: ReturnAnalysisResult = {
        skuId,
        productName: product.name,
        returnRate: Math.round(returnRate * 100) / 100,
        totalReturns,
        totalOrders,
        primaryReasons,
        temporalAnalysis,
        recommendations,
        riskLevel,
      };

      this.logger.log(`SKU退货原因分析完成: ${skuId}, 退货率: ${returnRate}%`, { 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 batchAnalyzeReturnReasons(skuIds: string[], traceId: string): Promise<ReturnAnalysisResult[]> {
    this.logger.log(`开始批量分析SKU退货原因, 数量: ${skuIds.length}`, { traceId });

    const results: ReturnAnalysisResult[] = [];

    for (const skuId of skuIds) {
      try {
        const result = await this.analyzeReturnReasons(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;
  }

  /**
   * 获取高退货率SKU列表
   * @param threshold 退货率阈值
   * @param limit 返回数量
   * @param traceId 链路追踪ID
   * @returns 高退货率SKU列表
   */
  async getHighReturnRateSkus(threshold: number = 10, limit: number = 10, traceId: string): Promise<Array<{
    skuId: string;
    productName: string;
    returnRate: number;
    totalReturns: number;
    totalOrders: number;
    primaryReason: string;
  }>> {
    this.logger.log(`获取高退货率SKU列表, 阈值: ${threshold}%, 限制: ${limit}`, { traceId });

    try {
      // 获取所有SKU的退货数据
      const returns = await this.prisma.return.findMany({
        include: {
          order: {
            include: {
              product: true,
            },
          },
        },
      });

      // 获取所有SKU的订单数据
      const orders = await this.prisma.order.findMany({
        include: {
          items: true,
        },
      });

      // 按SKU分组计算退货率
      const skuReturnStats = new Map<string, { returns: ReturnData[]; orders: Order[] }>();

      // 统计退货
      returns.forEach(ret => {
        if (!skuReturnStats.has(ret.skuId)) {
          skuReturnStats.set(ret.skuId, { returns: [], orders: [] });
        }
        skuReturnStats.get(ret.skuId)?.returns.push(ret);
      });

      // 统计订单
      orders.forEach(order => {
        order.items.forEach(item => {
          if (!skuReturnStats.has(item.skuId)) {
            skuReturnStats.set(item.skuId, { returns: [], orders: [] });
          }
          skuReturnStats.get(item.skuId)?.orders.push(order);
        });
      });

      // 计算退货率并筛选高退货率SKU
      const highReturnRateSkus = [];

      for (const [skuId, stats] of skuReturnStats.entries()) {
        const totalOrders = stats.orders.length;
        const totalReturns = stats.returns.length;
        const returnRate = totalOrders > 0 ? (totalReturns / totalOrders) * 100 : 0;

        if (returnRate >= threshold) {
          // 获取商品名称
          const product = await this.prisma.product.findFirst({
            where: {
              skus: {
                some: {
                  id: skuId,
                },
              },
            },
          });

          // 获取主要退货原因
          const primaryReasons = this.analyzePrimaryReasons(stats.returns);
          const primaryReason = primaryReasons.length > 0 ? primaryReasons[0].reason : '未知';

          highReturnRateSkus.push({
            skuId,
            productName: product?.name || '未知商品',
            returnRate: Math.round(returnRate * 100) / 100,
            totalReturns,
            totalOrders,
            primaryReason,
          });
        }
      }

      // 按退货率排序并限制数量
      highReturnRateSkus.sort((a, b) => b.returnRate - a.returnRate);

      this.logger.log(`获取高退货率SKU列表完成, 数量: ${highReturnRateSkus.length}`, { traceId });

      return highReturnRateSkus.slice(0, limit);
    } catch (error) {
      this.logger.error(`获取高退货率SKU列表失败: ${error.message}`, { traceId, error });
      throw error;
    }
  }

  /**
   * 分析主要退货原因
   */
  private analyzePrimaryReasons(returns: any[]): ReturnAnalysisResult['primaryReasons'] {
    // 统计各退货原因的数量
    const reasonCounts = new Map<string, number>();

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

    // 转换为数组并计算百分比
    const totalReturns = returns.length;
    const reasons = Array.from(reasonCounts.entries())
      .map(([reason, count]) => ({
        reason,
        count,
        percentage: totalReturns > 0 ? (count / totalReturns) * 100 : 0,
      }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 5); // 只返回前5个主要原因

    return reasons;
  }

  /**
   * 分析时间趋势
   */
  private analyzeTemporalTrends(returns: any[], orders: Order[]): ReturnAnalysisResult['temporalAnalysis'] {
    // 按周分组分析
    const weeklyData = new Map<string, { orders: number; returns: number }>();

    // 统计订单
    orders.forEach(order => {
      const weekKey = this.getWeekKey(order.createdAt);
      if (!weeklyData.has(weekKey)) {
        weeklyData.set(weekKey, { orders: 0, returns: 0 });
      }
      weeklyData.get(weekKey)!.orders++;
    });

    // 统计退货
    returns.forEach(ret => {
      const weekKey = this.getWeekKey(ret.createdAt);
      if (!weeklyData.has(weekKey)) {
        weeklyData.set(weekKey, { orders: 0, returns: 0 });
      }
      weeklyData.get(weekKey)!.returns++;
    });

    // 转换为数组并计算退货率
    const temporalData = Array.from(weeklyData.entries())
      .map(([period, data]) => ({
        period,
        returnRate: data.orders > 0 ? (data.returns / data.orders) * 100 : 0,
        orderCount: data.orders,
        returnCount: data.returns,
      }))
      .sort((a, b) => a.period.localeCompare(b.period));

    return temporalData;
  }

  /**
   * 获取周key
   */
  private getWeekKey(date: Date): string {
    const d = new Date(date);
    const year = d.getFullYear();
    const weekNumber = this.getWeekNumber(d);
    return `${year}-W${weekNumber}`;
  }

  /**
   * 获取周数
   */
  private getWeekNumber(date: Date): number {
    const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
    const dayNum = d.getUTCDay() || 7;
    d.setUTCDate(d.getUTCDate() + 4 - dayNum);
    const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
    return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1) / 7);
  }

  /**
   * 生成建议
   */
  private generateRecommendations(data: {
    returnRate: number;
    primaryReasons: ReturnAnalysisResult['primaryReasons'];
    temporalAnalysis: ReturnAnalysisResult['temporalAnalysis'];
    product: Product;
  }): string[] {
    const recommendations: string[] = [];

    // 基于退货率的建议
    if (data.returnRate > 20) {
      recommendations.push('建议考虑暂时下架该SKU，进行全面质量检查');
    } else if (data.returnRate > 10) {
      recommendations.push('建议优化产品描述和图片，确保与实际产品一致');
    }

    // 基于主要退货原因的建议
    const topReason = data.primaryReasons[0];
    if (topReason) {
      switch (topReason.reason) {
        case '质量问题':
          recommendations.push('建议加强质量控制，对供应商进行审核');
          break;
        case '尺寸不符':
          recommendations.push('建议提供更详细的尺寸表和测量指南');
          break;
        case '描述不符':
          recommendations.push('建议更新产品描述，确保与实际产品一致');
          break;
        case '物流损坏':
          recommendations.push('建议优化包装，选择更可靠的物流服务商');
          break;
        case '其他':
          recommendations.push('建议收集更详细的退货原因，以便针对性改进');
          break;
      }
    }

    // 基于时间趋势的建议
    if (data.temporalAnalysis.length > 1) {
      const recentTrend = this.analyzeTrend(data.temporalAnalysis);
      if (recentTrend === 'increasing') {
        recommendations.push('退货率呈上升趋势，建议立即采取措施');
      } else if (recentTrend === 'decreasing') {
        recommendations.push('退货率呈下降趋势，建议继续保持当前改进措施');
      }
    }

    // 通用建议
    recommendations.push('建议定期监控该SKU的退货情况，及时调整策略');

    return recommendations;
  }

  /**
   * 分析趋势
   */
  private analyzeTrend(data: ReturnAnalysisResult['temporalAnalysis']): 'increasing' | 'decreasing' | 'stable' {
    if (data.length < 2) return 'stable';

    const recentData = data.slice(-3); // 取最近3个周期的数据
    const firstRate = recentData[0].returnRate;
    const lastRate = recentData[recentData.length - 1].returnRate;

    const changeRate = ((lastRate - firstRate) / firstRate) * 100;

    if (changeRate > 10) {
      return 'increasing';
    } else if (changeRate < -10) {
      return 'decreasing';
    } else {
      return 'stable';
    }
  }

  /**
   * 评估风险等级
   */
  private assessRiskLevel(returnRate: number): 'low' | 'medium' | 'high' {
    if (returnRate > 20) {
      return 'high';
    } else if (returnRate > 10) {
      return 'medium';
    } else {
      return 'low';
    }
  }

  /**
   * 生成退货分析报告
   * @param period 时间周期（如：'week', 'month', 'quarter'）
   * @param traceId 链路追踪ID
   * @returns 退货分析报告
   */
  async generateReturnAnalysisReport(period: string, traceId: string) {
    this.logger.log(`生成退货分析报告, 周期: ${period}`, { traceId, period });

    try {
      // 计算时间范围
      const endDate = new Date();
      let startDate = new Date();

      switch (period) {
        case 'week':
          startDate.setDate(startDate.getDate() - 7);
          break;
        case 'month':
          startDate.setMonth(startDate.getMonth() - 1);
          break;
        case 'quarter':
          startDate.setMonth(startDate.getMonth() - 3);
          break;
        default:
          startDate.setMonth(startDate.getMonth() - 1);
      }

      // 获取时间范围内的退货数据
      const returns = await this.prisma.return.findMany({
        where: {
          createdAt: {
            gte: startDate,
            lte: endDate,
          },
        },
        include: {
          order: {
            include: {
              product: true,
            },
          },
        },
      });

      // 按SKU分组
      const skuGroups = new Map<string, typeof returns>();
      returns.forEach(ret => {
        if (!skuGroups.has(ret.skuId)) {
          skuGroups.set(ret.skuId, []);
        }
        skuGroups.get(ret.skuId)?.push(ret);
      });

      // 分析每个SKU
      const skuAnalyses = [];
      for (const [skuId, skuReturns] of skuGroups.entries()) {
        try {
          const analysis = await this.analyzeReturnReasons(skuId, traceId);
          skuAnalyses.push(analysis);
        } catch (error) {
          this.logger.error(`分析SKU ${skuId} 失败: ${error.message}`, { traceId, skuId });
        }
      }

      // 计算整体退货率
      const totalReturns = returns.length;
      const totalOrders = await this.prisma.order.count({
        where: {
          createdAt: {
            gte: startDate,
            lte: endDate,
          },
        },
      });
      const overallReturnRate = totalOrders > 0 ? (totalReturns / totalOrders) * 100 : 0;

      // 分析主要退货原因
      const overallReasons = this.analyzePrimaryReasons(returns);

      // 按风险等级分组
      const highRiskSkus = skuAnalyses.filter(analysis => analysis.riskLevel === 'high');
      const mediumRiskSkus = skuAnalyses.filter(analysis => analysis.riskLevel === 'medium');
      const lowRiskSkus = skuAnalyses.filter(analysis => analysis.riskLevel === 'low');

      const report = {
        period,
        timeRange: {
          start: startDate,
          end: endDate,
        },
        overallReturnRate: Math.round(overallReturnRate * 100) / 100,
        totalReturns,
        totalOrders,
        overallReasons,
        skuAnalyses,
        riskDistribution: {
          high: highRiskSkus.length,
          medium: mediumRiskSkus.length,
          low: lowRiskSkus.length,
        },
        highRiskSkus: highRiskSkus.map(sku => ({
          skuId: sku.skuId,
          productName: sku.productName,
          returnRate: sku.returnRate,
          primaryReason: sku.primaryReasons[0]?.reason || '未知',
        })),
      };

      this.logger.log(`生成退货分析报告完成`, { traceId, report });

      return report;
    } catch (error) {
      this.logger.error(`生成退货分析报告失败: ${error.message}`, { traceId, period, error });
      throw error;
    }
  }
}
