import { router, protectedProcedure, adminProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import { TRPCError } from '@trpc/server';
import { aiGameBuilderService, GameConcept, GeneratedGame } from '../aiGameBuilder.service.ts';
import { gameCustomizationEngine, GameVariant } from '../gameCustomizationEngine.ts';
import { batchGameGenerationSystem, BatchJob, GameAnalytics } from '../batchGameGeneration.ts';

export const aiGameBuilderRouter = router({
  /**
   * Create game concept from description
   */
  createConcept: adminProcedure
    .input(
      z.object({
        title: z.string().min(1),
        description: z.string().min(10),
        genre: z.enum(['slot', 'puzzle', 'action', 'strategy', 'arcade', 'card']),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const concept: GameConcept = {
          id: `concept-${Date.now()}`,
          title: input.title,
          description: input.description,
          genre: input.genre,
          targetAudience: 'all',
          theme: 'modern',
          mechanics: [],
          estimatedPlaytime: 5,
          createdAt: new Date(),
          createdBy: 'admin',
        };

        return concept;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to create game concept',
        });
      }
    }),

  /**
   * Generate game from concept
   */
  generateGame: adminProcedure
    .input(
      z.object({
        conceptId: z.string(),
        title: z.string(),
        description: z.string(),
        genre: z.enum(['slot', 'puzzle', 'action', 'strategy', 'arcade', 'card']),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const concept: GameConcept = {
          id: input.conceptId,
          title: input.title,
          description: input.description,
          genre: input.genre,
          targetAudience: 'all',
          theme: 'modern',
          mechanics: [],
          estimatedPlaytime: 5,
          createdAt: new Date(),
          createdBy: 'admin',
        };

        const game = await aiGameBuilderService.generateGameCode(concept);
        return game;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to generate game',
        });
      }
    }),

  /**
   * Get game details
   */
  getGame: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      // Mock implementation
      return {
        id: input.gameId,
        title: 'Sample Game',
        status: 'published',
        createdAt: new Date(),
      };
    }),

  /**
   * Validate game code
   */
  validateGame: adminProcedure
    .input(
      z.object({
        gameId: z.string(),
        htmlCode: z.string(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const game: GeneratedGame = {
          id: input.gameId,
          conceptId: '',
          title: '',
          description: '',
          htmlCode: input.htmlCode,
          cssCode: '',
          jsCode: '',
          thumbnailUrl: '',
          previewUrl: '',
          status: 'draft',
          createdAt: new Date(),
        };

        const validation = await aiGameBuilderService.validateGame(game);
        return validation;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Validation failed',
        });
      }
    }),

  /**
   * Deploy game
   */
  deployGame: adminProcedure
    .input(z.object({ gameId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        // Mock deployment
        return {
          success: true,
          gameId: input.gameId,
          url: `https://games.coinkrazy.com/${input.gameId}`,
          deployedAt: new Date(),
        };
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Deployment failed',
        });
      }
    }),

  /**
   * Create game variant
   */
  createVariant: adminProcedure
    .input(
      z.object({
        baseGameId: z.string(),
        name: z.string(),
        theme: z.string(),
        difficulty: z.enum(['easy', 'medium', 'hard', 'extreme']),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const theme = gameCustomizationEngine.getTheme(input.theme);
        if (!theme) {
          throw new TRPCError({
            code: 'NOT_FOUND',
            message: 'Theme not found',
          });
        }

        const variant = gameCustomizationEngine.createVariant(input.baseGameId, {
          name: input.name,
          theme,
        });

        gameCustomizationEngine.adjustDifficulty(variant.id, input.difficulty);

        return variant;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to create variant',
        });
      }
    }),

  /**
   * Get available themes
   */
  getThemes: protectedProcedure.query(async () => {
    return gameCustomizationEngine.getAllThemes();
  }),

  /**
   * Adjust game rewards
   */
  adjustRewards: adminProcedure
    .input(
      z.object({
        variantId: z.string(),
        minWin: z.number().optional(),
        maxWin: z.number().optional(),
        multiplier: z.number().optional(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const variant = gameCustomizationEngine.adjustRewards(input.variantId, {
          minWin: input.minWin,
          maxWin: input.maxWin,
          rewardMultiplier: input.multiplier,
        });

        if (!variant) {
          throw new TRPCError({
            code: 'NOT_FOUND',
            message: 'Variant not found',
          });
        }

        return variant;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to adjust rewards',
        });
      }
    }),

  /**
   * Create batch generation job
   */
  createBatchJob: adminProcedure
    .input(
      z.object({
        conceptId: z.string(),
        variantCount: z.number().min(1).max(10),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const job = batchGameGenerationSystem.createBatchJob(input.conceptId, input.variantCount);
        return job;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to create batch job',
        });
      }
    }),

  /**
   * Get batch job status
   */
  getBatchJobStatus: adminProcedure
    .input(z.object({ jobId: z.string() }))
    .query(async ({ input }) => {
      const job = batchGameGenerationSystem.getJobStatus(input.jobId);
      if (!job) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Job not found',
        });
      }
      return job;
    }),

  /**
   * Record game analytics
   */
  recordAnalytics: adminProcedure
    .input(
      z.object({
        gameId: z.string(),
        totalPlays: z.number().optional(),
        totalPlayers: z.number().optional(),
        engagementScore: z.number().optional(),
        winRate: z.number().optional(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const analytics = batchGameGenerationSystem.recordAnalytics(input.gameId, {
          totalPlays: input.totalPlays,
          totalPlayers: input.totalPlayers,
          engagementScore: input.engagementScore,
          winRate: input.winRate,
        });
        return analytics;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to record analytics',
        });
      }
    }),

  /**
   * Get game analytics
   */
  getAnalytics: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const analytics = batchGameGenerationSystem.getAnalytics(input.gameId);
      if (!analytics) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Analytics not found',
        });
      }
      return analytics;
    }),

  /**
   * Create A/B test
   */
  createABTest: adminProcedure
    .input(
      z.object({
        gameAId: z.string(),
        gameBId: z.string(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const test = batchGameGenerationSystem.createABTest(input.gameAId, input.gameBId);
        return test;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to create A/B test',
        });
      }
    }),

  /**
   * Get A/B test results
   */
  getABTestResults: protectedProcedure
    .input(z.object({ testId: z.string() }))
    .query(async ({ input }) => {
      const results = batchGameGenerationSystem.getABTestResults(input.testId);
      if (!results) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Test not found',
        });
      }
      return results;
    }),

  /**
   * Get top performing games
   */
  getTopPerformingGames: protectedProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(async ({ input }) => {
      return batchGameGenerationSystem.getTopPerformingGames(input.limit);
    }),

  /**
   * Get batch statistics
   */
  getBatchStats: adminProcedure.query(async () => {
    return batchGameGenerationSystem.getBatchStats();
  }),

  /**
   * Get customization stats
   */
  getCustomizationStats: adminProcedure.query(async () => {
    return gameCustomizationEngine.getVariantStats();
  }),

  /**
   * Get current wallet balance
   */
  getWalletBalance: protectedProcedure.query(async ({ ctx }) => {
    try {
      const { realtimeWalletIntegration } = await import('../realtimeWalletIntegration.ts');
      const balance = await realtimeWalletIntegration.loadWalletBalance(
        ctx.user.id.toString()
      );
      return balance;
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to load wallet balance',
      });
    }
  }),
});
