import { router, adminProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import { TRPCError } from '@trpc/server';
import { gamePerformanceMonitoringService } from '../gamePerformanceMonitoring.ts';
import { gameRecommendationEngine } from '../gameRecommendationEngine.ts';
import { gameTournamentSystem } from '../gameTournamentSystem.ts';

export const adminMonitoringRouter = router({
  /**
   * Get dashboard overview
   */
  getDashboardOverview: adminProcedure.query(async () => {
    try {
      const monitoringStats = gamePerformanceMonitoringService.getMonitoringStats();
      const recommendationStats = gameRecommendationEngine.getRecommendationStats();
      const tournamentStats = gameTournamentSystem.getAllTournamentsStats();

      return {
        monitoring: monitoringStats,
        recommendations: recommendationStats,
        tournaments: tournamentStats,
        timestamp: new Date(),
      };
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get dashboard overview',
      });
    }
  }),

  /**
   * Get game performance metrics
   */
  getGameMetrics: adminProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      try {
        const metrics = gamePerformanceMonitoringService.getLatestMetrics(input.gameId);
        if (!metrics) {
          throw new TRPCError({
            code: 'NOT_FOUND',
            message: 'Metrics not found',
          });
        }
        return metrics;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get game metrics',
        });
      }
    }),

  /**
   * Get all game health statuses
   */
  getAllGameHealth: adminProcedure.query(async () => {
    try {
      return gamePerformanceMonitoringService.getTopPerformingGames(100);
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get game health statuses',
      });
    }
  }),

  /**
   * Get critical games
   */
  getCriticalGames: adminProcedure.query(async () => {
    try {
      return gamePerformanceMonitoringService.getCriticalGames();
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get critical games',
      });
    }
  }),

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

        // Get all active alerts
        const allGames = gamePerformanceMonitoringService.getTopPerformingGames(100);
        const allAlerts = allGames.flatMap((g) => g.alerts);

        return allAlerts;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get active alerts',
        });
      }
    }),

  /**
   * 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',
        });
      }
    }),

  /**
   * Get top performing games
   */
  getTopPerformingGames: adminProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(async ({ input }) => {
      try {
        return gamePerformanceMonitoringService.getTopPerformingGames(input.limit);
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get top performing games',
        });
      }
    }),

  /**
   * Get monitoring statistics
   */
  getMonitoringStats: adminProcedure.query(async () => {
    try {
      return gamePerformanceMonitoringService.getMonitoringStats();
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get monitoring statistics',
      });
    }
  }),

  /**
   * Create tournament
   */
  createTournament: adminProcedure
    .input(
      z.object({
        name: z.string(),
        description: z.string(),
        gameId: z.string(),
        maxPlayers: z.number(),
        entryFee: z.number(),
        prizePool: z.number(),
      })
    )
    .mutation(async ({ input }) => {
      try {
        const tournament = gameTournamentSystem.createTournament({
          name: input.name,
          description: input.description,
          gameId: input.gameId,
          maxPlayers: input.maxPlayers,
          entryFee: input.entryFee,
          prizePool: input.prizePool,
        });

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

  /**
   * Start tournament
   */
  startTournament: adminProcedure
    .input(z.object({ tournamentId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        const success = gameTournamentSystem.startTournament(input.tournamentId);
        if (!success) {
          throw new TRPCError({
            code: 'BAD_REQUEST',
            message: 'Tournament cannot be started',
          });
        }

        return gameTournamentSystem.getTournament(input.tournamentId);
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to start tournament',
        });
      }
    }),

  /**
   * End tournament
   */
  endTournament: adminProcedure
    .input(z.object({ tournamentId: z.string() }))
    .mutation(async ({ input }) => {
      try {
        const rewards = gameTournamentSystem.endTournament(input.tournamentId);

        return {
          success: true,
          rewards: Object.fromEntries(rewards),
        };
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to end tournament',
        });
      }
    }),

  /**
   * Get active tournaments
   */
  getActiveTournaments: adminProcedure.query(async () => {
    try {
      return gameTournamentSystem.getActiveTournaments();
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get active tournaments',
      });
    }
  }),

  /**
   * Get tournament leaderboard
   */
  getTournamentLeaderboard: adminProcedure
    .input(z.object({ tournamentId: z.string() }))
    .query(async ({ input }) => {
      try {
        return gameTournamentSystem.getTournamentLeaderboard(input.tournamentId);
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get tournament leaderboard',
        });
      }
    }),

  /**
   * Get tournament statistics
   */
  getTournamentStats: adminProcedure
    .input(z.object({ tournamentId: z.string() }))
    .query(async ({ input }) => {
      try {
        const stats = gameTournamentSystem.getTournamentStats(input.tournamentId);
        if (!stats) {
          throw new TRPCError({
            code: 'NOT_FOUND',
            message: 'Tournament not found',
          });
        }

        return stats;
      } catch (error) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get tournament statistics',
        });
      }
    }),

  /**
   * Get all tournaments statistics
   */
  getAllTournamentsStats: adminProcedure.query(async () => {
    try {
      return gameTournamentSystem.getAllTournamentsStats();
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get all tournaments statistics',
      });
    }
  }),

  /**
   * Get recommendation statistics
   */
  getRecommendationStats: adminProcedure.query(async () => {
    try {
      return gameRecommendationEngine.getRecommendationStats();
    } catch (error) {
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get recommendation statistics',
      });
    }
  }),
});
