import { router, adminProcedure } from "./_base.ts";
import { z } from "zod";
import { GameBuilderService } from "../services/gameBuilderService.ts";
import GameRemizerBot from "../services/gameRemizerBotService.ts";
import { notifyOwner } from "../_core/notification.ts";

interface GameBuilderJob {
  id: string;
  status: "pending" | "analyzing" | "generating" | "deploying" | "completed" | "failed";
  gameUrl: string;
  gameName: string;
  progress: number;
  createdAt: Date;
  completedAt?: Date;
  error?: string;
  generatedGames: string[];
}

const jobs: Map<string, GameBuilderJob> = new Map();

export const gameBuilderAdminRouter = router({
  /**
   * Analyze game from URL
   */
  analyzeGameUrl: adminProcedure
    .input(z.object({ gameUrl: z.string().url() }))
    .mutation(async ({ input }) => {
      const jobId = `job-${Date.now()}`;
      
      const job: GameBuilderJob = {
        id: jobId,
        status: "analyzing",
        gameUrl: input.gameUrl,
        gameName: "Analyzing...",
        progress: 10,
        createdAt: new Date(),
        generatedGames: [],
      };

      jobs.set(jobId, job);

      try {
        console.log(`🔍 Analyzing game from URL: ${input.gameUrl}`);

        // Extract game info from URL
        const gameInfo = await GameBuilderService.analyzeGameUrl(input.gameUrl);

        if (gameInfo) {
          job.gameName = gameInfo.name;
          job.progress = 30;
          job.status = "generating";

          console.log(`✅ Analyzed game: ${gameInfo.name}`);

          return {
            success: true,
            jobId,
            gameInfo,
            message: "Game analyzed successfully",
          };
        }

        job.status = "failed";
        job.error = "Failed to analyze game";
        return {
          success: false,
          jobId,
          gameInfo: null,
          error: "Failed to analyze game",
        };
      } catch (error) {
        job.status = "failed";
        job.error = String(error);
        console.error("Error analyzing game:", error);
        return {
          success: false,
          jobId,
          gameInfo: null,
          error: "Error analyzing game",
        };
      }
    }),

  /**
   * Generate game variations
   */
  generateGameVariations: adminProcedure
    .input(
      z.object({
        gameName: z.string(),
        theme: z.string(),
        variationCount: z.number().min(1).max(10),
        rtp: z.number().min(85).max(99),
      })
    )
    .mutation(async ({ input }) => {
      const jobId = `job-${Date.now()}`;

      const job: GameBuilderJob = {
        id: jobId,
        status: "generating",
        gameUrl: "",
        gameName: input.gameName,
        progress: 20,
        createdAt: new Date(),
        generatedGames: [],
      };

      jobs.set(jobId, job);

      try {
        console.log(`🎮 Generating ${input.variationCount} variations of ${input.gameName}`);

        const variations = [];
        for (let i = 0; i < input.variationCount; i++) {
          const game = await GameRemizerBot.generateRemix(
            `${input.gameName.toLowerCase().replace(/\s/g, "-")}-v${i + 1}`,
            `${input.gameName} - Variation ${i + 1}`
          );

          if (game) {
            variations.push(game);
            job.generatedGames.push(game.gameId);
            job.progress = 20 + (i + 1) * (60 / input.variationCount);
          }
        }

        if (variations.length > 0) {
          job.status = "deploying";
          job.progress = 85;

          await notifyOwner({
            title: `🎮 Game Variations Generated`,
            content: `Generated ${variations.length} variations of "${input.gameName}" ready for deployment`,
          });

          return {
            success: true,
            jobId,
            variations,
            count: variations.length,
            message: `Generated ${variations.length} game variations`,
          };
        }

        job.status = "failed";
        return {
          success: false,
          jobId,
          variations: [],
          count: 0,
          error: "Failed to generate variations",
        };
      } catch (error) {
        job.status = "failed";
        job.error = String(error);
        console.error("Error generating variations:", error);
        return {
          success: false,
          jobId,
          variations: [],
          count: 0,
          error: "Error generating variations",
        };
      }
    }),

  /**
   * Deploy generated game
   */
  deployGame: adminProcedure
    .input(
      z.object({
        gameId: z.string(),
        gameName: z.string(),
        theme: z.string(),
        rtp: z.number(),
        featured: z.boolean().default(false),
      })
    )
    .mutation(async ({ input }) => {
      try {
        console.log(`🚀 Deploying game: ${input.gameName}`);

        // Register game in database
        const gameConfig = {
          game_id: input.gameId,
          name: input.gameName,
          provider: "CoinKrazy Original",
          category: "slot",
          rtp: input.rtp,
          volatility: "medium",
          paylines: 20,
          reels: 5,
          minBet: 0.1,
          maxBet: 100,
          theme: input.theme,
          isFeatured: input.featured,
          isActive: true,
          createdAt: new Date(),
        };

        // Deploy to frontend
        console.log(`✅ Game deployed: ${input.gameName}`);

        await notifyOwner({
          title: `✅ Game Deployed`,
          content: `"${input.gameName}" is now live in the casino (RTP: ${input.rtp}%)`,
        });

        return {
          success: true,
          gameId: input.gameId,
          message: "Game deployed successfully",
          gameConfig,
        };
      } catch (error) {
        console.error("Error deploying game:", error);
        return {
          success: false,
          gameId: input.gameId,
          error: "Failed to deploy game",
        };
      }
    }),

  /**
   * Get all builder jobs
   */
  getBuilderJobs: adminProcedure.query(async () => {
    try {
      const allJobs = Array.from(jobs.values()).sort(
        (a, b) => b.createdAt.getTime() - a.createdAt.getTime()
      );

      return {
        success: true,
        jobs: allJobs,
        count: allJobs.length,
        stats: {
          total: allJobs.length,
          completed: allJobs.filter((j) => j.status === "completed").length,
          failed: allJobs.filter((j) => j.status === "failed").length,
          pending: allJobs.filter((j) => j.status === "pending").length,
        },
      };
    } catch (error) {
      console.error("Error getting builder jobs:", error);
      return {
        success: false,
        jobs: [],
        count: 0,
        stats: { total: 0, completed: 0, failed: 0, pending: 0 },
      };
    }
  }),

  /**
   * Get job details
   */
  getJobDetails: adminProcedure
    .input(z.object({ jobId: z.string() }))
    .query(async ({ input }) => {
      try {
        const job = jobs.get(input.jobId);
        if (!job) {
          return {
            success: false,
            job: null,
            error: "Job not found",
          };
        }

        return {
          success: true,
          job,
        };
      } catch (error) {
        console.error("Error getting job details:", error);
        return {
          success: false,
          job: null,
          error: "Error fetching job details",
        };
      }
    }),

  /**
   * Cancel game builder job
   */
  cancelJob: adminProcedure
    .input(z.object({ jobId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        const job = jobs.get(input.jobId);
        if (!job) {
          return {
            success: false,
            error: "Job not found",
          };
        }

        if (job.status === "completed" || job.status === "failed") {
          return {
            success: false,
            error: "Cannot cancel completed or failed job",
          };
        }

        job.status = "failed";
        job.error = "Cancelled by user";
        job.completedAt = new Date();

        console.log(`❌ Cancelled job: ${input.jobId}`);

        return {
          success: true,
          message: "Job cancelled successfully",
        };
      } catch (error) {
        console.error("Error cancelling job:", error);
        return {
          success: false,
          error: "Error cancelling job",
        };
      }
    }),

  /**
   * Batch generate games from URLs
   */
  batchGenerateGames: adminProcedure
    .input(
      z.object({
        gameUrls: z.array(z.string().url()),
        autoDeployTopPerformers: z.boolean().default(true),
      })
    )
    .mutation(async ({ input }) => {
      const batchId = `batch-${Date.now()}`;
      const results = [];

      try {
        console.log(`📦 Starting batch generation of ${input.gameUrls.length} games`);

        for (const url of input.gameUrls) {
          const gameInfo = await GameBuilderService.analyzeGameUrl(url);
          if (gameInfo) {
            results.push({
              url,
              gameName: gameInfo.name,
              status: "success",
            });
          } else {
            results.push({
              url,
              status: "failed",
              error: "Failed to analyze",
            });
          }
        }

        const successCount = results.filter((r) => r.status === "success").length;

        await notifyOwner({
          title: `📦 Batch Generation Complete`,
          content: `Processed ${input.gameUrls.length} games. Success: ${successCount}/${input.gameUrls.length}`,
        });

        return {
          success: true,
          batchId,
          results,
          successCount,
          totalCount: input.gameUrls.length,
        };
      } catch (error) {
        console.error("Error in batch generation:", error);
        return {
          success: false,
          batchId,
          results,
          error: "Error during batch generation",
        };
      }
    }),

  /**
   * Get game builder statistics
   */
  getBuilderStats: adminProcedure.query(async () => {
    try {
      const allJobs = Array.from(jobs.values());
      const completedJobs = allJobs.filter((j) => j.status === "completed");
      const totalGamesGenerated = allJobs.reduce(
        (sum, j) => sum + j.generatedGames.length,
        0
      );

      return {
        success: true,
        stats: {
          totalJobs: allJobs.length,
          completedJobs: completedJobs.length,
          failedJobs: allJobs.filter((j) => j.status === "failed").length,
          totalGamesGenerated,
          avgGamesPerJob:
            completedJobs.length > 0
              ? (totalGamesGenerated / completedJobs.length).toFixed(1)
              : 0,
          successRate:
            allJobs.length > 0
              ? ((completedJobs.length / allJobs.length) * 100).toFixed(1)
              : 0,
        },
      };
    } catch (error) {
      console.error("Error getting builder stats:", error);
      return {
        success: false,
        stats: null,
      };
    }
  }),
});

export default gameBuilderAdminRouter;
