import db from '../config/database';
import { logger } from '../utils/logger';
import { UserAssetService } from './UserAssetService';
import { MemberLevel } from '../models/UserAsset';

export interface UserBehaviorData {
  userId: string;
  loginCount: number;
  lastLoginAt?: Date;
  pageViews: number;
  productViews: number;
  cartAdditions: number;
  wishlistCount: number;
  reviewCount: number;
  shareCount: number;
  referralCount: number;
  returnRate: number;
  complaintCount: number;
}

export interface UserValueScore {
  userId: string;
  tenantId: string;
  shopId: string;
  overallScore: number;
  scoreLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'VIP';
  dimensions: {
    spending: DimensionScore;
    loyalty: DimensionScore;
    engagement: DimensionScore;
    influence: DimensionScore;
    risk: DimensionScore;
  };
  recommendations: string[];
  predictedValue: number;
  churnRisk: number;
  traceId: string;
  calculatedAt: Date;
}

export interface DimensionScore {
  score: number;
  weight: number;
  weightedScore: number;
  factors: ScoreFactor[];
}

export interface ScoreFactor {
  name: string;
  value: number;
  normalizedValue: number;
  weight: number;
  description: string;
}

export interface UserValueAnalysisInput {
  tenantId: string;
  shopId: string;
  userId: string;
  traceId: string;
  taskId?: string;
  businessType: 'TOC' | 'TOB';
}

export interface UserValueReport {
  userId: string;
  tenantId: string;
  shopId: string;
  score: UserValueScore;
  segment: UserSegment;
  lifetimeValue: number;
  acquisitionCost: number;
  roi: number;
  nextBestAction: string;
  traceId: string;
}

export interface UserSegment {
  segmentId: string;
  segmentName: string;
  segmentType: 'VALUE_BASED' | 'BEHAVIOR_BASED' | 'LIFECYCLE_BASED';
  characteristics: string[];
  percentage: number;
}

export interface BatchAnalysisResult {
  totalUsers: number;
  averageScore: number;
  scoreDistribution: Record<string, number>;
  segmentDistribution: Record<string, number>;
  highValueUsers: string[];
  atRiskUsers: string[];
  traceId: string;
}

export class UserValueAnalysisService {
  private static readonly TABLE_NAME = 'cf_user_value_score';
  private static readonly SEGMENT_TABLE = 'cf_user_segment';

  private static readonly DIMENSION_WEIGHTS = {
    spending: 0.30,
    loyalty: 0.25,
    engagement: 0.20,
    influence: 0.15,
    risk: 0.10,
  };

  private static readonly SCORE_THRESHOLDS = {
    VIP: 85,
    HIGH: 70,
    MEDIUM: 50,
    LOW: 0,
  };

  static async initTable(): Promise<void> {
    const hasTable = await db.schema.hasTable(this.TABLE_NAME);
    if (!hasTable) {
      logger.info(`[UserValueAnalysisService] Creating ${this.TABLE_NAME} table...`);
      await db.schema.createTable(this.TABLE_NAME, (table) => {
        table.string('id', 36).primary();
        table.string('tenant_id', 64).notNullable().index();
        table.string('shop_id', 64).notNullable().index();
        table.string('user_id', 64).notNullable().index();
        table.decimal('overall_score', 5, 2).notNullable();
        table.enum('score_level', ['LOW', 'MEDIUM', 'HIGH', 'VIP']).notNullable();
        table.json('dimensions').notNullable();
        table.json('recommendations').notNullable();
        table.decimal('predicted_value', 12, 2).defaultTo(0);
        table.decimal('churn_risk', 5, 4).defaultTo(0);
        table.string('trace_id', 64).notNullable();
        table.string('task_id', 36);
        table.timestamp('calculated_at').defaultTo(db.fn.now());
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.timestamp('updated_at').defaultTo(db.fn.now());

        table.unique(['tenant_id', 'shop_id', 'user_id'], 'uk_value_user');
        table.index(['overall_score'], 'idx_value_score');
        table.index(['score_level'], 'idx_value_level');
      });
      logger.info(`[UserValueAnalysisService] Table ${this.TABLE_NAME} created`);
    }

    const hasSegmentTable = await db.schema.hasTable(this.SEGMENT_TABLE);
    if (!hasSegmentTable) {
      logger.info(`[UserValueAnalysisService] Creating ${this.SEGMENT_TABLE} table...`);
      await db.schema.createTable(this.SEGMENT_TABLE, (table) => {
        table.string('id', 36).primary();
        table.string('tenant_id', 64).notNullable().index();
        table.string('shop_id', 64).notNullable().index();
        table.string('user_id', 64).notNullable().index();
        table.string('segment_id', 64).notNullable();
        table.string('segment_name', 128).notNullable();
        table.enum('segment_type', ['VALUE_BASED', 'BEHAVIOR_BASED', 'LIFECYCLE_BASED']).notNullable();
        table.json('characteristics').notNullable();
        table.decimal('percentage', 5, 2).defaultTo(0);
        table.string('trace_id', 64).notNullable();
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.timestamp('updated_at').defaultTo(db.fn.now());

        table.unique(['tenant_id', 'shop_id', 'user_id'], 'uk_segment_user');
        table.index(['segment_id'], 'idx_segment_id');
      });
      logger.info(`[UserValueAnalysisService] Table ${this.SEGMENT_TABLE} created`);
    }
  }

  static async analyzeUserValue(input: UserValueAnalysisInput): Promise<UserValueScore> {
    const { tenantId, shopId, userId, traceId, taskId, businessType } = input;

    logger.info(`[UserValueAnalysisService] Starting user value analysis: userId=${userId}, tenantId=${tenantId}, traceId=${traceId}`);

    const asset = await UserAssetService.getByUserId(tenantId, shopId, userId);
    const behavior = await this.getUserBehaviorData(tenantId, shopId, userId, traceId);

    const spendingScore = await this.calculateSpendingScore(asset, behavior);
    const loyaltyScore = await this.calculateLoyaltyScore(asset, behavior);
    const engagementScore = await this.calculateEngagementScore(asset, behavior);
    const influenceScore = await this.calculateInfluenceScore(asset, behavior);
    const riskScore = await this.calculateRiskScore(asset, behavior);

    const dimensions = {
      spending: spendingScore,
      loyalty: loyaltyScore,
      engagement: engagementScore,
      influence: influenceScore,
      risk: riskScore,
    };

    const overallScore = this.calculateOverallScore(dimensions);
    const scoreLevel = this.determineScoreLevel(overallScore);
    const recommendations = this.generateRecommendations(dimensions, scoreLevel);
    const predictedValue = this.predictFutureValue(asset, overallScore);
    const churnRisk = this.calculateChurnRisk(asset, behavior, overallScore);

    const score: UserValueScore = {
      userId,
      tenantId,
      shopId,
      overallScore,
      scoreLevel,
      dimensions,
      recommendations,
      predictedValue,
      churnRisk,
      traceId,
      calculatedAt: new Date(),
    };

    await this.saveScore(score, taskId, businessType);

    logger.info(`[UserValueAnalysisService] User value analysis completed: userId=${userId}, score=${overallScore}, level=${scoreLevel}, traceId=${traceId}`);

    return score;
  }

  private static async getUserBehaviorData(
    tenantId: string,
    shopId: string,
    userId: string,
    traceId: string
  ): Promise<UserBehaviorData> {
    const defaultBehavior: UserBehaviorData = {
      userId,
      loginCount: 0,
      pageViews: 0,
      productViews: 0,
      cartAdditions: 0,
      wishlistCount: 0,
      reviewCount: 0,
      shareCount: 0,
      referralCount: 0,
      returnRate: 0,
      complaintCount: 0,
    };

    try {
      const behaviorTable = 'cf_user_behavior';
      const hasTable = await db.schema.hasTable(behaviorTable);
      
      if (!hasTable) {
        return defaultBehavior;
      }

      const record = await db(behaviorTable)
        .where({ tenant_id: tenantId, shop_id: shopId, user_id: userId })
        .first();

      if (!record) {
        return defaultBehavior;
      }

      return {
        userId,
        loginCount: Number(record.login_count) || 0,
        lastLoginAt: record.last_login_at,
        pageViews: Number(record.page_views) || 0,
        productViews: Number(record.product_views) || 0,
        cartAdditions: Number(record.cart_additions) || 0,
        wishlistCount: Number(record.wishlist_count) || 0,
        reviewCount: Number(record.review_count) || 0,
        shareCount: Number(record.share_count) || 0,
        referralCount: Number(record.referral_count) || 0,
        returnRate: Number(record.return_rate) || 0,
        complaintCount: Number(record.complaint_count) || 0,
      };
    } catch (error) {
      logger.error(`[UserValueAnalysisService] Failed to get behavior data: userId=${userId}, traceId=${traceId}`);
      return defaultBehavior;
    }
  }

  private static async calculateSpendingScore(
    asset: any,
    behavior: UserBehaviorData
  ): Promise<DimensionScore> {
    const factors: ScoreFactor[] = [];
    const totalSpent = asset?.totalSpent || 0;
    const totalOrders = asset?.totalOrders || 0;
    const avgOrderValue = totalOrders > 0 ? totalSpent / totalOrders : 0;

    const normalizedSpent = Math.min(totalSpent / 10000, 100);
    factors.push({
      name: 'total_spent',
      value: totalSpent,
      normalizedValue: normalizedSpent,
      weight: 0.4,
      description: `累计消费金额: ${totalSpent.toFixed(2)}`,
    });

    const normalizedOrders = Math.min(totalOrders / 50, 100);
    factors.push({
      name: 'total_orders',
      value: totalOrders,
      normalizedValue: normalizedOrders,
      weight: 0.3,
      description: `累计订单数: ${totalOrders}`,
    });

    const normalizedAOV = Math.min(avgOrderValue / 500, 100);
    factors.push({
      name: 'avg_order_value',
      value: avgOrderValue,
      normalizedValue: normalizedAOV,
      weight: 0.3,
      description: `平均订单金额: ${avgOrderValue.toFixed(2)}`,
    });

    const score = factors.reduce((sum, f) => sum + f.normalizedValue * f.weight, 0);
    const weight = this.DIMENSION_WEIGHTS.spending;

    return {
      score,
      weight,
      weightedScore: score * weight,
      factors,
    };
  }

  private static async calculateLoyaltyScore(
    asset: any,
    behavior: UserBehaviorData
  ): Promise<DimensionScore> {
    const factors: ScoreFactor[] = [];
    const memberLevel = asset?.memberLevel || 'BRONZE';
    const memberScore = asset?.memberScore || 0;
    const points = asset?.totalPoints || 0;

    const levelScores: Record<MemberLevel, number> = {
      BRONZE: 20,
      SILVER: 40,
      GOLD: 60,
      PLATINUM: 80,
      DIAMOND: 100,
    };

    const normalizedLevel = levelScores[memberLevel] || 20;
    factors.push({
      name: 'member_level',
      value: levelScores[memberLevel] || 20,
      normalizedValue: normalizedLevel,
      weight: 0.4,
      description: `会员等级: ${memberLevel}`,
    });

    const normalizedMemberScore = Math.min(memberScore / 10000, 100);
    factors.push({
      name: 'member_score',
      value: memberScore,
      normalizedValue: normalizedMemberScore,
      weight: 0.3,
      description: `会员积分: ${memberScore}`,
    });

    const normalizedPoints = Math.min(points / 5000, 100);
    factors.push({
      name: 'total_points',
      value: points,
      normalizedValue: normalizedPoints,
      weight: 0.3,
      description: `可用积分: ${points}`,
    });

    const score = factors.reduce((sum, f) => sum + f.normalizedValue * f.weight, 0);
    const weight = this.DIMENSION_WEIGHTS.loyalty;

    return {
      score,
      weight,
      weightedScore: score * weight,
      factors,
    };
  }

  private static async calculateEngagementScore(
    asset: any,
    behavior: UserBehaviorData
  ): Promise<DimensionScore> {
    const factors: ScoreFactor[] = [];

    const normalizedLogins = Math.min(behavior.loginCount / 100, 100);
    factors.push({
      name: 'login_count',
      value: behavior.loginCount,
      normalizedValue: normalizedLogins,
      weight: 0.25,
      description: `登录次数: ${behavior.loginCount}`,
    });

    const normalizedViews = Math.min(behavior.pageViews / 1000, 100);
    factors.push({
      name: 'page_views',
      value: behavior.pageViews,
      normalizedValue: normalizedViews,
      weight: 0.25,
      description: `页面浏览: ${behavior.pageViews}`,
    });

    const normalizedCart = Math.min(behavior.cartAdditions / 100, 100);
    factors.push({
      name: 'cart_additions',
      value: behavior.cartAdditions,
      normalizedValue: normalizedCart,
      weight: 0.2,
      description: `加购次数: ${behavior.cartAdditions}`,
    });

    const normalizedReviews = Math.min(behavior.reviewCount / 20, 100);
    factors.push({
      name: 'review_count',
      value: behavior.reviewCount,
      normalizedValue: normalizedReviews,
      weight: 0.15,
      description: `评价次数: ${behavior.reviewCount}`,
    });

    const normalizedWishlist = Math.min(behavior.wishlistCount / 50, 100);
    factors.push({
      name: 'wishlist_count',
      value: behavior.wishlistCount,
      normalizedValue: normalizedWishlist,
      weight: 0.15,
      description: `收藏商品: ${behavior.wishlistCount}`,
    });

    const score = factors.reduce((sum, f) => sum + f.normalizedValue * f.weight, 0);
    const weight = this.DIMENSION_WEIGHTS.engagement;

    return {
      score,
      weight,
      weightedScore: score * weight,
      factors,
    };
  }

  private static async calculateInfluenceScore(
    asset: any,
    behavior: UserBehaviorData
  ): Promise<DimensionScore> {
    const factors: ScoreFactor[] = [];

    const normalizedShares = Math.min(behavior.shareCount / 50, 100);
    factors.push({
      name: 'share_count',
      value: behavior.shareCount,
      normalizedValue: normalizedShares,
      weight: 0.4,
      description: `分享次数: ${behavior.shareCount}`,
    });

    const normalizedReferrals = Math.min(behavior.referralCount / 20, 100);
    factors.push({
      name: 'referral_count',
      value: behavior.referralCount,
      normalizedValue: normalizedReferrals,
      weight: 0.6,
      description: `推荐人数: ${behavior.referralCount}`,
    });

    const score = factors.reduce((sum, f) => sum + f.normalizedValue * f.weight, 0);
    const weight = this.DIMENSION_WEIGHTS.influence;

    return {
      score,
      weight,
      weightedScore: score * weight,
      factors,
    };
  }

  private static async calculateRiskScore(
    asset: any,
    behavior: UserBehaviorData
  ): Promise<DimensionScore> {
    const factors: ScoreFactor[] = [];

    const returnRiskScore = Math.max(0, 100 - behavior.returnRate * 100);
    factors.push({
      name: 'return_rate',
      value: behavior.returnRate,
      normalizedValue: returnRiskScore,
      weight: 0.5,
      description: `退货率: ${(behavior.returnRate * 100).toFixed(1)}%`,
    });

    const complaintRiskScore = Math.max(0, 100 - behavior.complaintCount * 10);
    factors.push({
      name: 'complaint_count',
      value: behavior.complaintCount,
      normalizedValue: complaintRiskScore,
      weight: 0.5,
      description: `投诉次数: ${behavior.complaintCount}`,
    });

    const score = factors.reduce((sum, f) => sum + f.normalizedValue * f.weight, 0);
    const weight = this.DIMENSION_WEIGHTS.risk;

    return {
      score,
      weight,
      weightedScore: score * weight,
      factors,
    };
  }

  private static calculateOverallScore(dimensions: Record<string, DimensionScore>): number {
    return Object.values(dimensions).reduce((sum, d) => sum + d.weightedScore, 0);
  }

  private static determineScoreLevel(score: number): 'LOW' | 'MEDIUM' | 'HIGH' | 'VIP' {
    if (score >= this.SCORE_THRESHOLDS.VIP) return 'VIP';
    if (score >= this.SCORE_THRESHOLDS.HIGH) return 'HIGH';
    if (score >= this.SCORE_THRESHOLDS.MEDIUM) return 'MEDIUM';
    return 'LOW';
  }

  private static generateRecommendations(
    dimensions: Record<string, DimensionScore>,
    level: string
  ): string[] {
    const recommendations: string[] = [];

    if (dimensions.spending.score < 50) {
      recommendations.push('建议通过优惠券或促销活动提升消费频次');
    }

    if (dimensions.loyalty.score < 50) {
      recommendations.push('建议加强会员权益宣传，提升会员等级意识');
    }

    if (dimensions.engagement.score < 50) {
      recommendations.push('建议通过个性化内容推送提升用户活跃度');
    }

    if (dimensions.influence.score < 50) {
      recommendations.push('建议设置分享奖励机制，激励用户传播');
    }

    if (dimensions.risk.score < 70) {
      recommendations.push('建议关注用户满意度，降低退货和投诉率');
    }

    if (level === 'VIP') {
      recommendations.push('建议提供专属客服和定制化服务');
    } else if (level === 'HIGH') {
      recommendations.push('建议提供VIP升级通道，培养忠诚度');
    } else if (level === 'LOW') {
      recommendations.push('建议通过新人礼包或首单优惠激活用户');
    }

    return recommendations;
  }

  private static predictFutureValue(asset: any, score: number): number {
    const totalSpent = asset?.totalSpent || 0;
    const growthFactor = 1 + (score / 100) * 0.5;
    return totalSpent * growthFactor;
  }

  private static calculateChurnRisk(
    asset: any,
    behavior: UserBehaviorData,
    score: number
  ): number {
    let risk = 0;

    if (behavior.loginCount < 5) risk += 0.3;
    if (behavior.returnRate > 0.2) risk += 0.2;
    if (behavior.complaintCount > 2) risk += 0.2;
    if (score < 40) risk += 0.3;

    const lastActiveAt = asset?.lastActiveAt;
    if (lastActiveAt) {
      const daysSinceActive = Math.floor(
        (Date.now() - new Date(lastActiveAt).getTime()) / (1000 * 60 * 60 * 24)
      );
      if (daysSinceActive > 30) risk += 0.2;
      if (daysSinceActive > 90) risk += 0.3;
    }

    return Math.min(risk, 1);
  }

  private static async saveScore(
    score: UserValueScore,
    taskId?: string,
    businessType?: 'TOC' | 'TOB'
  ): Promise<void> {
    const id = this.generateId();

    const existing = await db(this.TABLE_NAME)
      .where({
        tenant_id: score.tenantId,
        shop_id: score.shopId,
        user_id: score.userId,
      })
      .first();

    if (existing) {
      await db(this.TABLE_NAME)
        .where({ id: existing.id })
        .update({
          overall_score: score.overallScore,
          score_level: score.scoreLevel,
          dimensions: JSON.stringify(score.dimensions),
          recommendations: JSON.stringify(score.recommendations),
          predicted_value: score.predictedValue,
          churn_risk: score.churnRisk,
          trace_id: score.traceId,
          task_id: taskId || null,
          calculated_at: score.calculatedAt,
          updated_at: new Date(),
        });
    } else {
      await db(this.TABLE_NAME).insert({
        id,
        tenant_id: score.tenantId,
        shop_id: score.shopId,
        user_id: score.userId,
        overall_score: score.overallScore,
        score_level: score.scoreLevel,
        dimensions: JSON.stringify(score.dimensions),
        recommendations: JSON.stringify(score.recommendations),
        predicted_value: score.predictedValue,
        churn_risk: score.churnRisk,
        trace_id: score.traceId,
        task_id: taskId || null,
        calculated_at: score.calculatedAt,
      });
    }
  }

  static async getUserScore(
    tenantId: string,
    shopId: string,
    userId: string
  ): Promise<UserValueScore | null> {
    const record = await db(this.TABLE_NAME)
      .where({ tenant_id: tenantId, shop_id: shopId, user_id: userId })
      .first();

    if (!record) return null;

    return this.mapRowToScore(record);
  }

  static async batchAnalyze(
    tenantId: string,
    shopId: string,
    userIds: string[],
    traceId: string,
    businessType: 'TOC' | 'TOB'
  ): Promise<BatchAnalysisResult> {
    logger.info(`[UserValueAnalysisService] Starting batch analysis: tenantId=${tenantId}, userCount=${userIds.length}, traceId=${traceId}`);

    const scores: UserValueScore[] = [];
    const highValueUsers: string[] = [];
    const atRiskUsers: string[] = [];

    for (const userId of userIds) {
      try {
        const score = await this.analyzeUserValue({
          tenantId,
          shopId,
          userId,
          traceId,
          businessType,
        });
        scores.push(score);

        if (score.scoreLevel === 'VIP' || score.scoreLevel === 'HIGH') {
          highValueUsers.push(userId);
        }

        if (score.churnRisk > 0.5) {
          atRiskUsers.push(userId);
        }
      } catch (error) {
        logger.error(`[UserValueAnalysisService] Failed to analyze user: userId=${userId}, traceId=${traceId}`);
      }
    }

    const averageScore = scores.length > 0
      ? scores.reduce((sum, s) => sum + s.overallScore, 0) / scores.length
      : 0;

    const scoreDistribution: Record<string, number> = {
      LOW: 0,
      MEDIUM: 0,
      HIGH: 0,
      VIP: 0,
    };

    scores.forEach(s => {
      scoreDistribution[s.scoreLevel]++;
    });

    const segmentDistribution = await this.calculateSegmentDistribution(tenantId, shopId, traceId);

    return {
      totalUsers: userIds.length,
      averageScore,
      scoreDistribution,
      segmentDistribution,
      highValueUsers,
      atRiskUsers,
      traceId,
    };
  }

  private static async calculateSegmentDistribution(
    tenantId: string,
    shopId: string,
    traceId: string
  ): Promise<Record<string, number>> {
    const segments = await db(this.TABLE_NAME)
      .where({ tenant_id: tenantId, shop_id: shopId })
      .select('score_level')
      .count('* as count')
      .groupBy('score_level');

    const distribution: Record<string, number> = {};
    segments.forEach((s: any) => {
      distribution[s.score_level] = Number(s.count);
    });

    return distribution;
  }

  static async generateUserReport(
    tenantId: string,
    shopId: string,
    userId: string,
    traceId: string,
    businessType: 'TOC' | 'TOB'
  ): Promise<UserValueReport> {
    const score = await this.analyzeUserValue({
      tenantId,
      shopId,
      userId,
      traceId,
      businessType,
    });

    const segment = await this.determineUserSegment(score);
    const lifetimeValue = score.predictedValue;
    const acquisitionCost = await this.estimateAcquisitionCost(tenantId, shopId, userId, traceId);
    const roi = acquisitionCost > 0 ? (lifetimeValue - acquisitionCost) / acquisitionCost : 0;
    const nextBestAction = this.determineNextBestAction(score);

    return {
      userId,
      tenantId,
      shopId,
      score,
      segment,
      lifetimeValue,
      acquisitionCost,
      roi,
      nextBestAction,
      traceId,
    };
  }

  private static async determineUserSegment(score: UserValueScore): Promise<UserSegment> {
    let segmentId: string;
    let segmentName: string;
    const characteristics: string[] = [];

    if (score.scoreLevel === 'VIP') {
      segmentId = 'SEG_VIP';
      segmentName = 'VIP高价值用户';
      characteristics.push('高消费能力', '高忠诚度', '高影响力');
    } else if (score.scoreLevel === 'HIGH') {
      segmentId = 'SEG_HIGH';
      segmentName = '高潜力用户';
      characteristics.push('较高消费', '活跃度高', '有成长空间');
    } else if (score.scoreLevel === 'MEDIUM') {
      segmentId = 'SEG_MEDIUM';
      segmentName = '中等价值用户';
      characteristics.push('稳定消费', '中等活跃度');
    } else {
      segmentId = 'SEG_LOW';
      segmentName = '待激活用户';
      characteristics.push('低活跃度', '需重点运营');
    }

    return {
      segmentId,
      segmentName,
      segmentType: 'VALUE_BASED',
      characteristics,
      percentage: 0,
    };
  }

  private static async estimateAcquisitionCost(
    tenantId: string,
    shopId: string,
    userId: string,
    traceId: string
  ): Promise<number> {
    return 50;
  }

  private static determineNextBestAction(score: UserValueScore): string {
    if (score.churnRisk > 0.7) {
      return '立即进行用户召回，发送专属优惠券';
    }

    if (score.scoreLevel === 'VIP') {
      return '提供专属服务和VIP特权体验';
    }

    if (score.scoreLevel === 'HIGH') {
      return '推荐VIP升级路径，提供升级激励';
    }

    if (score.dimensions.engagement.score < 50) {
      return '推送个性化内容，提升用户活跃度';
    }

    if (score.dimensions.spending.score < 50) {
      return '发送首单优惠或限时折扣';
    }

    return '持续关注用户行为，适时推送相关内容';
  }

  private static generateId(): string {
    return `uvs_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  private static mapRowToScore(row: Record<string, any>): UserValueScore {
    return {
      userId: row.user_id,
      tenantId: row.tenant_id,
      shopId: row.shop_id,
      overallScore: Number(row.overall_score),
      scoreLevel: row.score_level,
      dimensions: JSON.parse(row.dimensions),
      recommendations: JSON.parse(row.recommendations),
      predictedValue: Number(row.predicted_value),
      churnRisk: Number(row.churn_risk),
      traceId: row.trace_id,
      calculatedAt: row.calculated_at,
    };
  }
}
