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

interface MerchantBehaviorData {
  merchantId: string;
  orderCount: number;
  totalSales: number;
  averageOrderValue: number;
  orderFrequency: number; // 日均订单数
  refundRate: number;
  activeDays: number; // 活跃天数
  lastOrderDate: Date;
  createdAt: Date;
}

interface BehaviorPredictionResult {
  merchantId: string;
  predictions: {
    futureSales: number; // 预测未来30天销售额
    orderTrend: 'increasing' | 'stable' | 'decreasing'; // 订单趋势
    churnRisk: 'low' | 'medium' | 'high'; // 流失风险
    growthPotential: 'high' | 'medium' | 'low'; // 增长潜力
  };
  confidence: number; // 预测置信度
  factors: {
    historicalTrend: number;
    recentActivity: number;
    customerRetention: number;
    marketSeasonality: number;
  };
  recommendations: string[];
}

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

  constructor(private readonly prisma: PrismaService) {}

  /**
   * 预测商户行为
   * @param merchantId 商户ID
   * @param traceId 链路追踪ID
   * @returns 商户行为预测结果
   */
  async predictMerchantBehavior(merchantId: string, traceId: string): Promise<BehaviorPredictionResult> {
    this.logger.log(`开始预测商户行为: ${merchantId}`, { traceId, merchantId });

    try {
      // 获取商户历史行为数据
      const behaviorData = await this.getMerchantBehaviorData(merchantId);

      // 分析历史趋势
      const historicalTrend = this.analyzeHistoricalTrend(merchantId);

      // 分析最近活动
      const recentActivity = this.analyzeRecentActivity(behaviorData);

      // 分析客户留存
      const customerRetention = this.analyzeCustomerRetention(merchantId);

      // 分析市场季节性
      const marketSeasonality = this.analyzeMarketSeasonality();

      const factors = {
        historicalTrend,
        recentActivity,
        customerRetention,
        marketSeasonality,
      };

      // 预测未来销售额
      const futureSales = this.predictFutureSales(behaviorData, factors);

      // 预测订单趋势
      const orderTrend = this.predictOrderTrend(historicalTrend, recentActivity);

      // 预测流失风险
      const churnRisk = this.predictChurnRisk(behaviorData, recentActivity);

      // 评估增长潜力
      const growthPotential = this.assessGrowthPotential(factors);

      // 计算预测置信度
      const confidence = this.calculateConfidence(factors);

      // 生成建议
      const recommendations = this.generateRecommendations({
        ...behaviorData,
        ...factors,
        predictions: {
          futureSales,
          orderTrend,
          churnRisk,
          growthPotential,
        },
      });

      const result: BehaviorPredictionResult = {
        merchantId,
        predictions: {
          futureSales,
          orderTrend,
          churnRisk,
          growthPotential,
        },
        confidence,
        factors,
        recommendations,
      };

      this.logger.log(`商户行为预测完成: ${merchantId}`, { traceId, result });

      return result;
    } catch (error) {
      this.logger.error(`商户行为预测失败: ${error.message}`, { traceId, merchantId, error });
      throw error;
    }
  }

  /**
   * 批量预测商户行为
   * @param merchantIds 商户ID列表
   * @param traceId 链路追踪ID
   * @returns 商户行为预测结果列表
   */
  async batchPredictMerchantBehavior(merchantIds: string[], traceId: string): Promise<BehaviorPredictionResult[]> {
    this.logger.log(`开始批量预测商户行为, 数量: ${merchantIds.length}`, { traceId });

    const results: BehaviorPredictionResult[] = [];

    for (const merchantId of merchantIds) {
      try {
        const result = await this.predictMerchantBehavior(merchantId, traceId);
        results.push(result);
      } catch (error) {
        this.logger.error(`批量预测商户行为失败: ${merchantId}, 错误: ${error.message}`, { traceId, merchantId });
      }
    }

    this.logger.log(`批量预测商户行为完成, 成功: ${results.length}/${merchantIds.length}`, { traceId });

    return results;
  }

  /**
   * 获取商户行为数据
   */
  private async getMerchantBehaviorData(merchantId: string): Promise<MerchantBehaviorData> {
    // 获取商户基本信息
    const merchant = await this.prisma.merchant.findUnique({
      where: { id: merchantId },
    });

    if (!merchant) {
      throw new Error(`商户不存在: ${merchantId}`);
    }

    // 获取商户订单数据
    const orders = await this.prisma.order.findMany({
      where: { merchantId },
      select: {
        id: true,
        totalAmount: true,
        status: true,
        createdAt: true,
      },
    });

    // 计算基本统计数据
    const orderCount = orders.length;
    const totalSales = orders.reduce((sum, order) => sum + order.totalAmount, 0);
    const averageOrderValue = orderCount > 0 ? totalSales / orderCount : 0;

    // 计算活跃天数
    const activeDays = new Set(orders.map(order => order.createdAt.toISOString().split('T')[0])).size;

    // 计算日均订单数
    const daysSinceCreation = merchant.createdAt ? 
      Math.max(1, Math.floor((new Date().getTime() - merchant.createdAt.getTime()) / (1000 * 60 * 60 * 24))) : 1;
    const orderFrequency = orderCount / daysSinceCreation;

    // 计算退款率
    const refundedOrders = orders.filter(order => order.status === 'REFUNDED').length;
    const refundRate = orderCount > 0 ? refundedOrders / orderCount : 0;

    // 获取最后订单日期
    const lastOrder = orders.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())[0];
    const lastOrderDate = lastOrder ? lastOrder.createdAt : merchant.createdAt;

    return {
      merchantId,
      orderCount,
      totalSales,
      averageOrderValue,
      orderFrequency,
      refundRate,
      activeDays,
      lastOrderDate,
      createdAt: merchant.createdAt,
    };
  }

  /**
   * 分析历史趋势
   */
  private async analyzeHistoricalTrend(merchantId: string): Promise<number> {
    // 这里可以实现更复杂的趋势分析逻辑
    // 例如：分析过去3个月的订单增长趋势
    return Math.random() * 0.5 + 0.5; // 模拟趋势值 (0.5-1.0)
  }

  /**
   * 分析最近活动
   */
  private analyzeRecentActivity(behaviorData: MerchantBehaviorData): number {
    // 计算最近30天的活跃程度
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    const daysSinceLastOrder = Math.floor((new Date().getTime() - behaviorData.lastOrderDate.getTime()) / (1000 * 60 * 60 * 24));
    const recentActivity = Math.max(0, 1 - (daysSinceLastOrder / 30));

    return recentActivity;
  }

  /**
   * 分析客户留存
   */
  private async analyzeCustomerRetention(merchantId: string): Promise<number> {
    // 这里可以实现更复杂的客户留存分析逻辑
    // 例如：分析重复购买率
    return Math.random() * 0.3 + 0.7; // 模拟留存率 (0.7-1.0)
  }

  /**
   * 分析市场季节性
   */
  private analyzeMarketSeasonality(): number {
    // 这里可以实现更复杂的季节性分析逻辑
    // 例如：根据当前月份分析季节性因素
    const month = new Date().getMonth() + 1;
    // 假设Q4是销售旺季
    if (month >= 10 || month <= 2) {
      return 1.2; // 旺季
    } else if (month >= 3 && month <= 5) {
      return 0.9; // 淡季
    } else {
      return 1.0; // 正常
    }
  }

  /**
   * 预测未来销售额
   */
  private predictFutureSales(behaviorData: MerchantBehaviorData, factors: any): number {
    // 基于历史数据和因素预测未来30天销售额
    const dailySales = behaviorData.totalSales / Math.max(1, behaviorData.activeDays);
    const basePrediction = dailySales * 30;

    // 应用各种因素的影响
    const adjustedPrediction = basePrediction * 
      (1 + (factors.historicalTrend - 0.5) * 0.3) *
      (1 + (factors.recentActivity - 0.5) * 0.2) *
      factors.marketSeasonality;

    return Math.max(0, Math.round(adjustedPrediction));
  }

  /**
   * 预测订单趋势
   */
  private predictOrderTrend(historicalTrend: number, recentActivity: number): 'increasing' | 'stable' | 'decreasing' {
    const combinedScore = (historicalTrend + recentActivity) / 2;

    if (combinedScore > 0.7) {
      return 'increasing';
    } else if (combinedScore > 0.4) {
      return 'stable';
    } else {
      return 'decreasing';
    }
  }

  /**
   * 预测流失风险
   */
  private predictChurnRisk(behaviorData: MerchantBehaviorData, recentActivity: number): 'low' | 'medium' | 'high' {
    const daysSinceLastOrder = Math.floor((new Date().getTime() - behaviorData.lastOrderDate.getTime()) / (1000 * 60 * 60 * 24));
    const activityScore = recentActivity;

    if (daysSinceLastOrder > 60 || activityScore < 0.3) {
      return 'high';
    } else if (daysSinceLastOrder > 30 || activityScore < 0.6) {
      return 'medium';
    } else {
      return 'low';
    }
  }

  /**
   * 评估增长潜力
   */
  private assessGrowthPotential(factors: any): 'high' | 'medium' | 'low' {
    const combinedScore = (factors.historicalTrend + factors.customerRetention) / 2;

    if (combinedScore > 0.8) {
      return 'high';
    } else if (combinedScore > 0.6) {
      return 'medium';
    } else {
      return 'low';
    }
  }

  /**
   * 计算预测置信度
   */
  private calculateConfidence(factors: any): number {
    // 基于数据完整性和因素稳定性计算置信度
    const dataCompleteness = 0.9; // 假设数据完整性较好
    const factorConsistency = (factors.historicalTrend + factors.recentActivity + factors.customerRetention) / 3;

    const confidence = dataCompleteness * factorConsistency;
    return Math.round(confidence * 100);
  }

  /**
   * 生成建议
   */
  private generateRecommendations(data: any): string[] {
    const recommendations: string[] = [];

    if (data.predictions.churnRisk === 'high') {
      recommendations.push('建议主动联系商户，了解经营情况并提供支持');
    }

    if (data.predictions.orderTrend === 'decreasing') {
      recommendations.push('建议优化产品展示和营销策略，提升订单量');
    }

    if (data.predictions.growthPotential === 'high') {
      recommendations.push('建议为商户提供高级功能和增值服务，支持其业务增长');
    }

    if (data.refundRate > 0.1) {
      recommendations.push('建议帮助商户优化产品质量和客户服务，降低退款率');
    }

    if (data.averageOrderValue < 100) {
      recommendations.push('建议引导商户增加高价值产品或实施捆绑销售策略');
    }

    return recommendations.length > 0 ? recommendations : ['商户经营状况稳定，继续保持'];
  }

  /**
   * 获取高风险商户列表
   * @param limit 返回数量
   * @param traceId 链路追踪ID
   * @returns 高风险商户列表
   */
  async getHighRiskMerchants(limit: number = 10, traceId: string): Promise<Array<{ merchantId: string; companyName: string; riskLevel: string; reason: string }>> {
    this.logger.log(`获取高风险商户列表, 限制: ${limit}`, { traceId });

    try {
      // 获取所有活跃商户
      const merchants = await this.prisma.merchant.findMany({
        where: { status: 'ACTIVE' },
        select: {
          id: true,
          companyName: true,
        },
      });

      const merchantIds = merchants.map(m => m.id);
      const predictions = await this.batchPredictMerchantBehavior(merchantIds, traceId);

      // 筛选高风险商户
      const highRiskMerchants = predictions
        .filter(p => p.predictions.churnRisk === 'high')
        .map(prediction => {
          const merchant = merchants.find(m => m.id === prediction.merchantId);
          return {
            merchantId: prediction.merchantId,
            companyName: merchant?.companyName || '未知商户',
            riskLevel: prediction.predictions.churnRisk,
            reason: prediction.recommendations[0] || '商户活动度低，存在流失风险',
          };
        })
        .slice(0, limit);

      this.logger.log(`获取高风险商户列表完成, 数量: ${highRiskMerchants.length}`, { traceId });

      return highRiskMerchants;
    } catch (error) {
      this.logger.error(`获取高风险商户列表失败: ${error.message}`, { traceId, error });
      throw error;
    }
  }
}
