import { invokeLLM } from "./_core/llm.ts";

interface GamePerformance {
  gameId: string;
  gameName: string;
  theme: string;
  revenue: number;
  players: number;
  engagement: number;
  roi: number;
  forecast: number;
}

interface PlayerSegment {
  segment: string;
  size: number;
  avgSpend: number;
  preferredTheme: string;
  engagement: number;
}

interface GameRecommendation {
  gameId: string;
  gameName: string;
  action: "remix" | "create" | "promote";
  reason: string;
  expectedROI: number;
  targetSegments: string[];
  priority: "high" | "medium" | "low";
  estimatedRevenue: number;
}

export class AutomatedGameRecommendations {
  /**
   * Generate game recommendations based on performance data and player preferences
   */
  static async generateRecommendations(
    games: GamePerformance[],
    segments: PlayerSegment[]
  ): Promise<GameRecommendation[]> {
    try {
      // Identify underperforming games that should be remixed
      const underperformers = games.filter((g) => g.roi < 2.5);

      // Identify top performers to use as templates
      const topPerformers = games.sort((a, b) => b.roi - a.roi).slice(0, 3);

      // Identify theme gaps
      const coveredThemes = new Set(games.map((g) => g.theme));
      const preferredThemes = new Set(segments.map((s) => s.preferredTheme));
      const missingThemes = Array.from(preferredThemes).filter((t) => !coveredThemes.has(t));

      // Use LLM to generate recommendations
      const prompt = `
Based on the following game performance data and player preferences, generate strategic game recommendations:

Games:
${JSON.stringify(games, null, 2)}

Player Segments:
${JSON.stringify(segments, null, 2)}

Underperforming games (ROI < 2.5):
${JSON.stringify(underperformers, null, 2)}

Top performers (high ROI):
${JSON.stringify(topPerformers, null, 2)}

Missing themes (not covered but preferred):
${JSON.stringify(missingThemes, null, 2)}

Generate 5-7 specific recommendations with:
1. Game ID or name
2. Action (remix/create/promote)
3. Reason based on data
4. Expected ROI improvement
5. Target player segments
6. Priority level
7. Estimated revenue impact

Format as JSON array of recommendations.
`;

      const response = await invokeLLM({
        messages: [
          {
            role: "system",
            content:
              "You are a game portfolio optimization expert. Generate strategic recommendations based on performance data and player preferences.",
          },
          {
            role: "user",
            content: prompt,
          },
        ],
        response_format: {
          type: "json_schema",
          json_schema: {
            name: "game_recommendations",
            strict: true,
            schema: {
              type: "object",
              properties: {
                recommendations: {
                  type: "array",
                  items: {
                    type: "object",
                    properties: {
                      gameId: { type: "string" },
                      gameName: { type: "string" },
                      action: { type: "string", enum: ["remix", "create", "promote"] },
                      reason: { type: "string" },
                      expectedROI: { type: "number" },
                      targetSegments: { type: "array", items: { type: "string" } },
                      priority: { type: "string", enum: ["high", "medium", "low"] },
                      estimatedRevenue: { type: "number" },
                    },
                    required: [
                      "gameId",
                      "gameName",
                      "action",
                      "reason",
                      "expectedROI",
                      "targetSegments",
                      "priority",
                      "estimatedRevenue",
                    ],
                    additionalProperties: false,
                  },
                },
              },
              required: ["recommendations"],
              additionalProperties: false,
            },
          },
        },
      });

      const content = response.choices[0].message.content;
      if (!content) return [];

      const parsed = JSON.parse(content);
      return parsed.recommendations || [];
    } catch (error) {
      console.error("Error generating recommendations:", error);
      return this.generateFallbackRecommendations(games, segments);
    }
  }

  /**
   * Fallback recommendations based on simple heuristics
   */
  private static generateFallbackRecommendations(
    games: GamePerformance[],
    segments: PlayerSegment[]
  ): GameRecommendation[] {
    const recommendations: GameRecommendation[] = [];

    // Recommend remixing underperformers
    games
      .filter((g) => g.roi < 2.5)
      .forEach((game) => {
        recommendations.push({
          gameId: game.gameId,
          gameName: game.gameName,
          action: "remix",
          reason: `Low ROI (${game.roi.toFixed(1)}x). Recommend remixing with top-performing theme.`,
          expectedROI: game.roi * 1.5,
          targetSegments: segments
            .filter((s) => s.preferredTheme === game.theme)
            .map((s) => s.segment),
          priority: "high",
          estimatedRevenue: game.revenue * 1.5,
        });
      });

    // Recommend creating games for missing themes
    const coveredThemes = new Set(games.map((g) => g.theme));
    segments
      .filter((s) => !coveredThemes.has(s.preferredTheme))
      .forEach((segment) => {
        recommendations.push({
          gameId: `new-${segment.preferredTheme}`,
          gameName: `${segment.preferredTheme} ${segment.segment} Game`,
          action: "create",
          reason: `${segment.segment} segment prefers ${segment.preferredTheme} theme but no game available.`,
          expectedROI: 3.0,
          targetSegments: [segment.segment],
          priority: "medium",
          estimatedRevenue: segment.size * segment.avgSpend * 0.3,
        });
      });

    // Recommend promoting top performers
    games
      .sort((a, b) => b.roi - a.roi)
      .slice(0, 2)
      .forEach((game) => {
        recommendations.push({
          gameId: game.gameId,
          gameName: game.gameName,
          action: "promote",
          reason: `High ROI (${game.roi.toFixed(1)}x) and engagement (${(game.engagement * 100).toFixed(0)}%). Increase marketing spend.`,
          expectedROI: game.roi * 1.2,
          targetSegments: segments.map((s) => s.segment),
          priority: "high",
          estimatedRevenue: game.revenue * 1.3,
        });
      });

    return recommendations.sort((a, b) => {
      const priorityOrder = { high: 0, medium: 1, low: 2 };
      return priorityOrder[a.priority] - priorityOrder[b.priority];
    });
  }

  /**
   * Calculate recommendation confidence score
   */
  static calculateConfidence(recommendation: GameRecommendation, games: GamePerformance[]): number {
    const game = games.find((g) => g.gameId === recommendation.gameId);
    if (!game) return 0.6; // New game, lower confidence

    // Higher confidence for games with more data (more players)
    const playerConfidence = Math.min(game.players / 5000, 1);

    // Higher confidence for recommendations with higher expected ROI
    const roiConfidence = Math.min(recommendation.expectedROI / 5, 1);

    // Average confidence
    return (playerConfidence + roiConfidence) / 2;
  }
}
