import { Injectable, Logger } from '@nestjs/common';
import { db } from '../../config/database';

interface ReturnData {
  id: string;
  orderId: string;
  productId: string;
  skuId: string;
  reason: string;
  status: string;
  returnDate: Date;
  refundAmount: number;
  createdAt: Date;
  updatedAt: Date;
}

interface ReturnAnalysisResult {
  totalReturns: number;
  totalRefundAmount: number;
  returnRate: number;
  topReturnReasons: Array<{
    reason: string;
    count: number;
    percentage: number;
  }>;
  productReturnRates: Array<{
    productId: string;
    productName: string;
    returnCount: number;
    returnRate: number;
  }>;
  monthlyTrend: Array<{
    month: string;
    returnCount: number;
    refundAmount: number;
  }>;
}

interface ReturnRiskAlert {
  productId: string;
  productName: string;
  riskLevel: 'high' | 'medium' | 'low';
  returnRate: number;
  threshold: number;
  recommendation: string;
}

/**
 * [BE-RET-001] 退货分析服务
 * 负责退货数据统计、退货原因分析、退货趋势预测
 * AI注意: 所有退货分析操作必须通过此服务进行
 */
@Injectable()
export class ReturnAnalysisService {
  private readonly logger = new Logger(ReturnAnalysisService.name);

  constructor() {}

  /**
   * 分析退货数据
   * @param tenantId 租户ID
   * @param startDate 开始日期
   * @param endDate 结束日期
   * @param traceId 链路追踪ID
   * @returns 退货分析结果
   */
  async analyzeReturns(
    tenantId: string,
    startDate: Date,
    endDate: Date,
    traceId: string
  ): Promise<ReturnAnalysisResult> {
    this.logger.log(`开始分析退货数据: ${tenantId}`, { traceId, tenantId, startDate, endDate });

    try {
      const returns = await db('cf_return')
        .where('tenant_id', tenantId)
        .whereBetween('return_date', [startDate, endDate])
        .select('*');

      const totalReturns = returns.length;
      const totalRefundAmount = returns.reduce((sum, r) => sum + (r.refund_amount || 0), 0);
      const returnRate = await this.calculateReturnRate(tenantId, startDate, endDate);
      const topReturnReasons = await this.analyzeReturnReasons(returns);
      const productReturnRates = await this.analyzeProductReturnRates(tenantId, returns);
      const monthlyTrend = await this.analyzeMonthlyTrend(tenantId, startDate, endDate);

      const result: ReturnAnalysisResult = {
        totalReturns,
        totalRefundAmount,
        returnRate,
        topReturnReasons,
        productReturnRates,
        monthlyTrend,
      };

      this.logger.log(`退货数据分析完成: ${tenantId}`, { traceId, result });

      return result;
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      this.logger.error(`退货数据分析失败: ${errorMessage}`, { traceId, tenantId, error });
      throw error;
    }
  }

  /**
   * 识别退货风险
   * @param tenantId 租户ID
   * @param threshold 退货率阈值
   * @param traceId 链路追踪ID
   * @returns 退货风险预警列表
   */
  async identifyReturnRisks(
    tenantId: string,
    threshold: number,
    traceId: string
  ): Promise<ReturnRiskAlert[]> {
    this.logger.log(`开始识别退货风险: ${tenantId}`, { traceId, tenantId, threshold });

    try {
      const products = await db('cf_product')
        .where('tenant_id', tenantId)
        .select('*');

      const alerts: ReturnRiskAlert[] = [];

      for (const product of products) {
        const productReturns = await db('cf_return')
          .where('tenant_id', tenantId)
          .where('product_id', product.id)
          .select('*');

        if (productReturns.length === 0) continue;

        const productOrders = await db('cf_order')
          .where('tenant_id', tenantId)
          .where('product_id', product.id)
          .count('* as count');

        const orderCountResult = productOrders[0] as any;
        const orderCount = orderCountResult?.count || 0;
        const returnRate = (productReturns.length / orderCount) * 100;

        if (returnRate > threshold) {
          alerts.push({
            productId: product.id,
            productName: product.name,
            riskLevel: returnRate > threshold * 1.5 ? 'high' : 'medium',
            returnRate,
            threshold,
            recommendation: this.generateRiskRecommendation(returnRate, threshold),
          });
        }
      }

      this.logger.log(`退货风险识别完成: ${tenantId}`, { traceId, alertCount: alerts.length });

      return alerts;
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : String(error);
      this.logger.error(`退货风险识别失败: ${errorMessage}`, { traceId, tenantId, error });
      throw error;
    }
  }

  /**
   * 计算退货率
   */
  private async calculateReturnRate(tenantId: string, startDate: Date, endDate: Date): Promise<number> {
    const orderCount = await db('cf_order')
      .where('tenant_id', tenantId)
      .whereBetween('created_at', [startDate, endDate])
      .count('* as count');

    const returnCount = await db('cf_return')
      .where('tenant_id', tenantId)
      .whereBetween('return_date', [startDate, endDate])
      .count('* as count');

    const orderCountResult = orderCount[0] as any;
    const returnCountResult = returnCount[0] as any;
    const totalOrders = orderCountResult?.count || 0;
    const totalReturns = returnCountResult?.count || 0;

    if (totalOrders === 0) return 0;

    return (totalReturns / totalOrders) * 100;
  }

  /**
   * 分析退货原因
   */
  private async analyzeReturnReasons(returns: any[]): Promise<Array<{
    reason: string;
    count: number;
    percentage: number;
  }>> {
    const reasonCounts = new Map<string, number>();

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

    const totalReturns = returns.length;
    const sortedReasons = Array.from(reasonCounts.entries())
      .map(([reason, count]) => ({
        reason,
        count,
        percentage: (count / totalReturns) * 100,
      }))
      .sort((a, b) => b.count - a.count)
      .slice(0, 10);

    return sortedReasons;
  }

  /**
   * 分析产品退货率
   */
  private async analyzeProductReturnRates(
    tenantId: string,
    returns: any[]
  ): Promise<Array<{
    productId: string;
    productName: string;
    returnCount: number;
    returnRate: number;
  }>> {
    const productReturnCounts = new Map<string, number>();

    returns.forEach(r => {
      const productId = r.product_id;
      productReturnCounts.set(productId, (productReturnCounts.get(productId) || 0) + 1);
    });

    const productReturnRates: Array<{
      productId: string;
      productName: string;
      returnCount: number;
      returnRate: number;
    }> = [];

    for (const [productId, returnCount] of productReturnCounts.entries()) {
      const product = await db('cf_product')
        .where('id', productId)
        .first();

      if (!product) continue;

      const productOrders = await db('cf_order')
        .where('tenant_id', tenantId)
        .where('product_id', productId)
        .count('* as count');

      const productOrdersResult = productOrders[0] as any;
      const orderCount = productOrdersResult?.count || 0;
      const returnRate = orderCount > 0 ? (returnCount / orderCount) * 100 : 0;

      productReturnRates.push({
        productId,
        productName: product.name,
        returnCount,
        returnRate,
      });
    }

    return productReturnRates
      .sort((a, b) => b.returnRate - a.returnRate)
      .slice(0, 20);
  }

  /**
   * 分析月度趋势
   */
  private async analyzeMonthlyTrend(
    tenantId: string,
    startDate: Date,
    endDate: Date
  ): Promise<Array<{
    month: string;
    returnCount: number;
    refundAmount: number;
  }>> {
    const monthlyReturns = await db('cf_return')
      .where('tenant_id', tenantId)
      .whereBetween('return_date', [startDate, endDate])
      .select('*');

    const monthlyData = new Map<string, { count: number; amount: number }>();

    monthlyReturns.forEach(r => {
      const month = new Date(r.return_date).toISOString().substring(0, 7);
      const data = monthlyData.get(month) || { count: 0, amount: 0 };
      data.count++;
      data.amount += r.refund_amount || 0;
      monthlyData.set(month, data);
    });

    return Array.from(monthlyData.entries())
      .map(([month, data]) => ({
        month,
        returnCount: data.count,
        refundAmount: data.amount,
      }))
      .sort((a, b) => a.month.localeCompare(b.month));
  }

  /**
   * 生成风险建议
   */
  private generateRiskRecommendation(returnRate: number, threshold: number): string {
    if (returnRate > threshold * 2) {
      return '退货率极高，建议立即下架该产品并进行质量检查';
    } else if (returnRate > threshold * 1.5) {
      return '退货率较高，建议优化产品描述和图片，加强质量控制';
    } else {
      return '退货率略高于阈值，建议分析退货原因并改进产品';
    }
  }
}
