import EnhancedGameBuilderLLM from "./enhancedGameBuilderLLM.ts";

export interface BatchAnalysisJob {
  jobId: string;
  status: "pending" | "processing" | "completed" | "failed";
  totalGames: number;
  analyzedGames: number;
  failedGames: number;
  results: Array<{
    url: string;
    status: "success" | "failed";
    game?: any;
    error?: string;
  }>;
  createdAt: Date;
  completedAt?: Date;
  progress: number;
}

/**
 * Batch Game Analyzer Service
 * Processes multiple game URLs in parallel for bulk portfolio expansion
 */
export class BatchGameAnalyzer {
  private static jobs: Map<string, BatchAnalysisJob> = new Map();

  /**
   * Start batch analysis of game URLs
   */
  static async startBatchAnalysis(gameUrls: string[]): Promise<string> {
    const jobId = `batch-${Date.now()}`;

    const job: BatchAnalysisJob = {
      jobId,
      status: "pending",
      totalGames: gameUrls.length,
      analyzedGames: 0,
      failedGames: 0,
      results: [],
      createdAt: new Date(),
      progress: 0,
    };

    this.jobs.set(jobId, job);

    // Start processing in background
    this.processBatch(jobId, gameUrls).catch((error) => {
      console.error("Batch processing error:", error);
      job.status = "failed";
    });

    return jobId;
  }

  /**
   * Process batch of games
   */
  private static async processBatch(jobId: string, gameUrls: string[]): Promise<void> {
    const job = this.jobs.get(jobId);
    if (!job) return;

    job.status = "processing";

    // Process games in parallel (max 5 at a time to avoid rate limiting)
    const batchSize = 5;
    for (let i = 0; i < gameUrls.length; i += batchSize) {
      const batch = gameUrls.slice(i, i + batchSize);
      const promises = batch.map((url) => this.analyzeGameUrl(url, job));

      await Promise.all(promises);

      // Update progress
      job.progress = Math.round(((i + batchSize) / gameUrls.length) * 100);
    }

    job.status = "completed";
    job.completedAt = new Date();
  }

  /**
   * Analyze single game URL
   */
  private static async analyzeGameUrl(
    url: string,
    job: BatchAnalysisJob
  ): Promise<void> {
    try {
      console.log(`🔍 Analyzing game: ${url}`);

      const game = await EnhancedGameBuilderLLM.analyzeGameFromUrl(url);

      if (game) {
        job.results.push({
          url,
          status: "success",
          game,
        });
        job.analyzedGames++;
        console.log(`✅ Successfully analyzed: ${game.name}`);
      } else {
        job.results.push({
          url,
          status: "failed",
          error: "Failed to analyze game",
        });
        job.failedGames++;
        console.error(`❌ Failed to analyze: ${url}`);
      }
    } catch (error) {
      job.results.push({
        url,
        status: "failed",
        error: error instanceof Error ? error.message : "Unknown error",
      });
      job.failedGames++;
      console.error(`❌ Error analyzing ${url}:`, error);
    }
  }

  /**
   * Get batch job status
   */
  static getJobStatus(jobId: string): BatchAnalysisJob | null {
    return this.jobs.get(jobId) || null;
  }

  /**
   * Get all jobs
   */
  static getAllJobs(): BatchAnalysisJob[] {
    return Array.from(this.jobs.values());
  }

  /**
   * Export batch results as CSV
   */
  static exportBatchResultsAsCSV(jobId: string): string | null {
    const job = this.jobs.get(jobId);
    if (!job) return null;

    const headers = [
      "URL",
      "Status",
      "Game Name",
      "RTP",
      "Volatility",
      "Paylines",
      "Reels",
      "Min Bet",
      "Max Bet",
      "Theme",
      "Error",
    ];

    const rows = job.results.map((result) => [
      result.url,
      result.status,
      result.game?.name || "",
      result.game?.rtp || "",
      result.game?.volatility || "",
      result.game?.paylines || "",
      result.game?.reels || "",
      result.game?.minBet || "",
      result.game?.maxBet || "",
      result.game?.theme || "",
      result.error || "",
    ]);

    const csv = [headers, ...rows].map((row) => row.map((cell) => `"${cell}"`).join(",")).join("\n");

    return csv;
  }

  /**
   * Clear completed job
   */
  static clearJob(jobId: string): boolean {
    return this.jobs.delete(jobId);
  }
}

export default BatchGameAnalyzer;
