import { router, protectedProcedure, adminProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import { TRPCError } from '@trpc/server';
import { aiGameCasinoIntegrationService } from '../aiGameCasinoIntegration.ts';
import { gameTemplateLibraryService } from '../gameTemplateLibrary.ts';
import { gamePerformanceMonitoringService } from '../gamePerformanceMonitoring.ts';

export const gameIntegrationRouter = router({
  /**
   * Register AI-generated game
   */
  registerGame: adminProcedure
    .input(
      z.object({
        gameId: z.string(),
        title: z.string(),
        genre: z.enum(['slot', 'puzzle', 'action', 'strategy', 'arcade', 'card']),
        htmlCode: z.string(),
        thumbnailUrl: z.string(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const registration = aiGameCasinoIntegrationService.registerGame({
          gameId: input.gameId,
          title: input.title,
          genre: input.genre,
          htmlCode: input.htmlCode,
          thumbnailUrl: input.thumbnailUrl,
        });

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

  /**
   * Deploy game to casino
   */
  deployGame: adminProcedure
    .input(z.object({ registrationId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        const deployment = await aiGameCasinoIntegrationService.deployGame(input.registrationId);
        return deployment;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Deployment failed',
        });
      }
    }),

  /**
   * Get active games
   */
  getActiveGames: protectedProcedure.query(async () => {
    return aiGameCasinoIntegrationService.getActiveGames();
  }),

  /**
   * Get games by genre
   */
  getGamesByGenre: protectedProcedure
    .input(z.object({ genre: z.string() }))
    .query(async ({ input }) => {
      return aiGameCasinoIntegrationService.getGamesByGenre(input.genre);
    }),

  /**
   * Get game templates
   */
  getTemplates: protectedProcedure
    .input(z.object({ genre: z.string().optional() }))
    .query(async ({ input }) => {
      if (input.genre) {
        return gameTemplateLibraryService.getTemplatesByGenre(input.genre);
      }
      return gameTemplateLibraryService.getAllTemplates();
    }),

  /**
   * Render template
   */
  renderTemplate: adminProcedure
    .input(
      z.object({
        templateId: z.string(),
        variables: z.record(z.any()),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const rendered = gameTemplateLibraryService.renderTemplate(input.templateId, input.variables);
        return { success: true, html: rendered };
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Template rendering failed',
        });
      }
    }),

  /**
   * Start game monitoring
   */
  startMonitoring: adminProcedure
    .input(z.object({ gameId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        gamePerformanceMonitoringService.startMonitoring(input.gameId);
        return { success: true, message: `Monitoring started for ${input.gameId}` };
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to start monitoring',
        });
      }
    }),

  /**
   * Get game metrics
   */
  getMetrics: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const metrics = gamePerformanceMonitoringService.getLatestMetrics(input.gameId);
      if (!metrics) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Metrics not found',
        });
      }
      return metrics;
    }),

  /**
   * Get game health status
   */
  getHealthStatus: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const health = gamePerformanceMonitoringService.getHealthStatus(input.gameId);
      if (!health) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Health status not found',
        });
      }
      return health;
    }),

  /**
   * Get active alerts
   */
  getActiveAlerts: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      return gamePerformanceMonitoringService.getActiveAlerts(input.gameId);
    }),

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

  /**
   * Get critical games
   */
  getCriticalGames: adminProcedure.query(async () => {
    return gamePerformanceMonitoringService.getCriticalGames();
  }),

  /**
   * Get monitoring statistics
   */
  getMonitoringStats: adminProcedure.query(async () => {
    return gamePerformanceMonitoringService.getMonitoringStats();
  }),

  /**
   * Get integration statistics
   */
  getIntegrationStats: adminProcedure.query(async () => {
    return aiGameCasinoIntegrationService.getIntegrationStats();
  }),

  /**
   * Get template statistics
   */
  getTemplateStats: protectedProcedure.query(async () => {
    return gameTemplateLibraryService.getTemplateStats();
  }),

  /**
   * Search templates
   */
  searchTemplates: protectedProcedure
    .input(z.object({ query: z.string() }))
    .query(async ({ input }) => {
      return gameTemplateLibraryService.searchTemplates(input.query);
    }),

  /**
   * Record game play
   */
  recordGamePlay: protectedProcedure
    .input(
      z.object({
        registrationId: z.string(),
        playerId: z.string(),
        betAmount: z.number(),
        winAmount: z.number(),
        duration: z.number(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        aiGameCasinoIntegrationService.recordGamePlay(input.registrationId, {
          playerId: input.playerId,
          betAmount: input.betAmount,
          winAmount: input.winAmount,
          duration: input.duration,
        });

        return { success: true };
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to record game play',
        });
      }
    }),

  /**
   * Resolve alert
   */
  resolveAlert: adminProcedure
    .input(z.object({ gameId: z.string(), alertId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        const alert = gamePerformanceMonitoringService.resolveAlert(input.gameId, input.alertId);
        return alert;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to resolve alert',
        });
      }
    }),
});
