/**
 * Revenue Forecasting Model
 * Predicts game revenue based on theme, RTP, and player cohort data
 */
export interface RevenueForecast {
  gameId: string;
  gameName: string;
  theme: string;
  rtp: number;
  volatility: string;
  predictedDailyRevenue: number;
  predictedMonthlyRevenue: number;
  predictedYearlyRevenue: number;
  confidenceInterval: {
    lower: number;
    upper: number;
  };
  keyDrivers: string[];
  riskFactors: string[];
  confidence: number;
}

export interface SegmentRevenueImpact {
  segment: string;
  expectedAdoptionRate: number;
  revenueContribution: number;
  playerLifetimeValue: number;
}

export class RevenueForecastingModel {
  /**
   * Forecast game revenue
   */
  static forecastGameRevenue(gameConfig: {
    gameId: string;
    gameName: string;
    theme: string;
    rtp: number;
    volatility: string;
    bonusFeatures: string[];
    paylines: number;
  }): RevenueForecast {
    // Base revenue calculation
    const baseMultiplier = this.getThemeMultiplier(gameConfig.theme);
    const rtpAdjustment = gameConfig.rtp > 96 ? 0.95 : gameConfig.rtp < 95 ? 1.05 : 1.0;
    const volatilityMultiplier = this.getVolatilityMultiplier(gameConfig.volatility);
    const bonusMultiplier = 1 + gameConfig.bonusFeatures.length * 0.1;

    const baseDailyRevenue = 5000; // Base daily revenue estimate
    const predictedDailyRevenue = baseDailyRevenue * baseMultiplier * rtpAdjustment * volatilityMultiplier * bonusMultiplier;

    const predictedMonthlyRevenue = predictedDailyRevenue * 30;
    const predictedYearlyRevenue = predictedDailyRevenue * 365;

    // Confidence interval (±20%)
    const confidenceInterval = {
      lower: predictedDailyRevenue * 0.8,
      upper: predictedDailyRevenue * 1.2,
    };

    // Key drivers
    const keyDrivers = [
      `${gameConfig.theme} theme appeals to target audience`,
      `${gameConfig.rtp}% RTP attracts ${gameConfig.rtp > 96 ? "value-conscious" : "high-risk"} players`,
      `${gameConfig.volatility} volatility suits ${this.getVolatilityAudience(gameConfig.volatility)} players`,
      `${gameConfig.bonusFeatures.length} bonus features increase engagement`,
    ];

    // Risk factors
    const riskFactors = [];
    if (gameConfig.rtp < 94) riskFactors.push("Low RTP may reduce player trust");
    if (gameConfig.volatility === "high") riskFactors.push("High volatility may cause player churn");
    if (gameConfig.bonusFeatures.length < 2) riskFactors.push("Limited bonus features may reduce engagement");

    const confidence = this.calculateConfidence(gameConfig);

    return {
      gameId: gameConfig.gameId,
      gameName: gameConfig.gameName,
      theme: gameConfig.theme,
      rtp: gameConfig.rtp,
      volatility: gameConfig.volatility,
      predictedDailyRevenue: Math.round(predictedDailyRevenue),
      predictedMonthlyRevenue: Math.round(predictedMonthlyRevenue),
      predictedYearlyRevenue: Math.round(predictedYearlyRevenue),
      confidenceInterval: {
        lower: Math.round(confidenceInterval.lower),
        upper: Math.round(confidenceInterval.upper),
      },
      keyDrivers,
      riskFactors,
      confidence,
    };
  }

  /**
   * Forecast segment-specific revenue
   */
  static forecastSegmentRevenue(
    gameConfig: {
      theme: string;
      rtp: number;
      volatility: string;
    },
    segment: {
      name: string;
      playerCount: number;
      averageSpend: number;
      themePreferences: Record<string, number>;
      engagementScore: number;
    }
  ): SegmentRevenueImpact {
    const themeMatch = segment.themePreferences[gameConfig.theme] || 0.3;
    const rtpBonus = gameConfig.rtp > 96 ? 1.1 : gameConfig.rtp < 95 ? 0.9 : 1.0;
    const engagementBonus = segment.engagementScore / 10;

    const adoptionRate = Math.min(themeMatch * rtpBonus * engagementBonus, 0.8);
    const activePlayersInSegment = segment.playerCount * adoptionRate;
    const revenueContribution = activePlayersInSegment * segment.averageSpend * 0.2; // 20% of spend as revenue

    // Estimate lifetime value
    const playerLifetimeValue = segment.averageSpend * 5; // Assume 5x average spend over lifetime

    return {
      segment: segment.name,
      expectedAdoptionRate: adoptionRate,
      revenueContribution: Math.round(revenueContribution),
      playerLifetimeValue: Math.round(playerLifetimeValue),
    };
  }

  /**
   * Compare revenue potential across themes
   */
  static compareThemeRevenuePotential(): Array<{
    theme: string;
    multiplier: number;
    targetAudience: string;
    estimatedMonthlyRevenue: number;
  }> {
    const themes = ["Luxury", "Vegas", "Asian", "Ocean", "Fruit Slots", "Holiday", "Retro"];

    return themes.map((theme) => ({
      theme,
      multiplier: this.getThemeMultiplier(theme),
      targetAudience: this.getThemeAudience(theme),
      estimatedMonthlyRevenue: Math.round(5000 * this.getThemeMultiplier(theme) * 30),
    }));
  }

  /**
   * Forecast ROI for game creation
   */
  static forecastGameROI(gameConfig: {
    theme: string;
    rtp: number;
    volatility: string;
    developmentCost: number;
  }): {
    breakEvenDays: number;
    firstYearROI: number;
    paybackPeriod: string;
  } {
    const forecast = this.forecastGameRevenue({
      gameId: "temp",
      gameName: "ROI Forecast",
      theme: gameConfig.theme,
      rtp: gameConfig.rtp,
      volatility: gameConfig.volatility,
      bonusFeatures: ["Free Spins", "Multiplier"],
      paylines: 20,
    });

    const dailyRevenue = forecast.predictedDailyRevenue;
    const breakEvenDays = Math.ceil(gameConfig.developmentCost / dailyRevenue);
    const firstYearRevenue = dailyRevenue * 365;
    const firstYearROI = ((firstYearRevenue - gameConfig.developmentCost) / gameConfig.developmentCost) * 100;

    const months = Math.floor(breakEvenDays / 30);
    const days = breakEvenDays % 30;
    const paybackPeriod = `${months}m ${days}d`;

    return {
      breakEvenDays,
      firstYearROI: Math.round(firstYearROI),
      paybackPeriod,
    };
  }

  /**
   * Get theme multiplier
   */
  private static getThemeMultiplier(theme: string): number {
    const multipliers: Record<string, number> = {
      Luxury: 1.4,
      Vegas: 1.3,
      Asian: 1.25,
      Ocean: 1.15,
      "Fruit Slots": 1.0,
      Holiday: 1.2,
      Retro: 0.9,
    };

    return multipliers[theme] || 1.0;
  }

  /**
   * Get volatility multiplier
   */
  private static getVolatilityMultiplier(volatility: string): number {
    const multipliers: Record<string, number> = {
      low: 1.0,
      medium: 1.1,
      high: 1.2,
    };

    return multipliers[volatility] || 1.0;
  }

  /**
   * Get volatility audience
   */
  private static getVolatilityAudience(volatility: string): string {
    const audiences: Record<string, string> = {
      low: "conservative",
      medium: "balanced",
      high: "risk-seeking",
    };

    return audiences[volatility] || "general";
  }

  /**
   * Get theme audience
   */
  private static getThemeAudience(theme: string): string {
    const audiences: Record<string, string> = {
      Luxury: "High-value players",
      Vegas: "Experienced players",
      Asian: "Asian market players",
      Ocean: "Adventure seekers",
      "Fruit Slots": "Casual players",
      Holiday: "Seasonal players",
      Retro: "Nostalgic players",
    };

    return audiences[theme] || "General audience";
  }

  /**
   * Calculate confidence score
   */
  private static calculateConfidence(gameConfig: {
    rtp: number;
    volatility: string;
    bonusFeatures: string[];
    paylines: number;
  }): number {
    let confidence = 0.7; // Base confidence

    // Adjust based on RTP
    if (gameConfig.rtp >= 95 && gameConfig.rtp <= 97) confidence += 0.1;
    else if (gameConfig.rtp < 94 || gameConfig.rtp > 98) confidence -= 0.1;

    // Adjust based on bonus features
    if (gameConfig.bonusFeatures.length >= 3) confidence += 0.1;
    else if (gameConfig.bonusFeatures.length < 2) confidence -= 0.05;

    // Adjust based on paylines
    if (gameConfig.paylines >= 15 && gameConfig.paylines <= 30) confidence += 0.05;

    return Math.min(Math.max(confidence, 0.5), 1.0);
  }
}

export default RevenueForecastingModel;
