import type { Message } from "../_core/llm.ts";
import { invokeLLM } from "../_core/llm.ts";
import { generateImage } from "../_core/imageGeneration.ts";
import { storagePut } from "../storage.ts";

export interface GameGenerationRequest {
  gameType: "slot" | "card" | "dice" | "puzzle" | "roulette" | "bingo" | "scratch";
  gameName: string;
  theme: string;
  difficulty: "easy" | "medium" | "hard";
  description?: string;
  rtp?: number;
  volatility?: "low" | "medium" | "high";
  maxWin?: number;
  minBet?: number;
  maxBet?: number;
}

export interface GeneratedGame {
  name: string;
  description: string;
  rules: string[];
  mechanics: {
    paylines?: number;
    reels?: number;
    symbols?: string[];
    bonusFeatures?: string[];
    multipliers?: number[];
  };
  rtp: number;
  volatility: "low" | "medium" | "high";
  maxWin: number;
  minBet: number;
  maxBet: number;
  theme: string;
  difficulty: "easy" | "medium" | "hard";
}

export class AIGameBuilderService {
  /**
   * Generate a complete game configuration using AI
   */
  static async generateGame(request: GameGenerationRequest): Promise<GeneratedGame> {
    const systemPrompt = this.buildSystemPrompt(request.gameType);
    const userPrompt = this.buildUserPrompt(request);

    const messages: Message[] = [
      { role: "system", content: systemPrompt },
      { role: "user", content: userPrompt },
    ];

    const response = await invokeLLM({
      messages,
      response_format: {
        type: "json_schema",
        json_schema: {
          name: "game_config",
          strict: true,
          schema: {
            type: "object",
            properties: {
              name: { type: "string", description: "Game name" },
              description: { type: "string", description: "Game description" },
              rules: {
                type: "array",
                items: { type: "string" },
                description: "List of game rules",
              },
              mechanics: {
                type: "object",
                properties: {
                  paylines: { type: "number" },
                  reels: { type: "number" },
                  symbols: {
                    type: "array",
                    items: { type: "string" },
                  },
                  bonusFeatures: {
                    type: "array",
                    items: { type: "string" },
                  },
                  multipliers: {
                    type: "array",
                    items: { type: "number" },
                  },
                },
              },
              rtp: { type: "number", description: "Return to Player percentage" },
              volatility: {
                type: "string",
                enum: ["low", "medium", "high"],
              },
              maxWin: { type: "number" },
              minBet: { type: "number" },
              maxBet: { type: "number" },
              theme: { type: "string" },
              difficulty: {
                type: "string",
                enum: ["easy", "medium", "hard"],
              },
            },
            required: [
              "name",
              "description",
              "rules",
              "mechanics",
              "rtp",
              "volatility",
              "maxWin",
              "minBet",
              "maxBet",
              "theme",
              "difficulty",
            ],
          },
        },
      },
    });

    const content = response.choices[0].message.content;
    if (typeof content !== "string") {
      throw new Error("Invalid LLM response format");
    }

    const gameConfig = JSON.parse(content) as GeneratedGame;
    return gameConfig;
  }

  /**
   * Generate game assets (thumbnail, symbols, etc.)
   */
  static async generateGameAssets(
    gameName: string,
    theme: string,
    gameType: string
  ): Promise<{
    thumbnailUrl: string;
    symbolUrls: string[];
  }> {
    // Generate thumbnail
    const thumbnailPrompt = `Create a professional game thumbnail for a ${gameType} game called "${gameName}" with ${theme} theme. 
    The thumbnail should be vibrant, eye-catching, and suitable for a casino game. 
    Include the game name prominently. 
    Style: modern, high-quality, casino-appropriate.
    Dimensions: 300x300 pixels.`;

    const { url: thumbnailUrl } = await generateImage({
      prompt: thumbnailPrompt,
    });

    // Generate symbol images (5 symbols for slot games)
    const symbolUrls: string[] = [];
    const symbolTypes = ["diamond", "gold", "ruby", "emerald", "sapphire"];

    for (const symbol of symbolTypes) {
      const symbolPrompt = `Create a single game symbol for a ${gameType} game with ${theme} theme. 
      The symbol should be a ${symbol} with a ${theme} aesthetic. 
      Style: modern, casino-quality, isolated on transparent background.
      Size: 100x100 pixels.`;

      const { url: symbolUrl } = await generateImage({
        prompt: symbolPrompt,
      });

      symbolUrls.push(symbolUrl);
    }

    return {
      thumbnailUrl,
      symbolUrls,
    };
  }

  /**
   * Save generated game to storage
   */
  static async saveGameAsset(
    assetName: string,
    assetData: Buffer,
    mimeType: string
  ): Promise<string> {
    const fileKey = `games/ai-generated/${Date.now()}-${assetName}`;
    const { url } = await storagePut(fileKey, assetData, mimeType);
    return url;
  }

  /**
   * Build system prompt for game generation
   */
  private static buildSystemPrompt(gameType: string): string {
    return `You are an expert casino game designer with deep knowledge of game mechanics, probability, and player psychology.
    You specialize in creating engaging ${gameType} games that balance fun with responsible gaming.
    
    When designing games:
    - Ensure RTP (Return to Player) is between 92-98%
    - Create balanced difficulty levels
    - Include engaging bonus features
    - Design mechanics that encourage responsible play
    - Consider player retention and engagement
    
    Always respond with valid JSON matching the specified schema.`;
  }

  /**
   * Build user prompt for game generation
   */
  private static buildUserPrompt(request: GameGenerationRequest): string {
    return `Create a new ${request.gameType} game with the following specifications:
    
    Game Name: ${request.gameName}
    Theme: ${request.theme}
    Difficulty: ${request.difficulty}
    Description: ${request.description || "A fun and engaging casino game"}
    
    Target RTP: ${request.rtp || 96}%
    Volatility: ${request.volatility || "medium"}
    Max Win: ${request.maxWin || 10000}
    Min Bet: ${request.minBet || 0.01}
    Max Bet: ${request.maxBet || 100}
    
    Please generate a complete game configuration with:
    1. Engaging game rules
    2. Detailed mechanics (paylines, reels, symbols, bonus features)
    3. Balanced RTP and volatility
    4. Clear difficulty progression
    5. Bonus features that enhance gameplay
    
    Ensure the game is fair, engaging, and follows responsible gaming principles.`;
  }
}
