/**
 * VIP Monitoring tRPC Router
 * Real-time VIP tier progression, rewards, and analytics
 */

import { z } from 'zod';
import { protectedProcedure, publicProcedure, router } from '../_core/trpc.ts';
import {
  getPlayerVIPTier,
  getVIPTierStats,
  getPlayerVIPRewards,
  trackTierProgression,
  getVIPLeaderboard,
  getVIPAnalytics,
  getRewardRedemptionHistory,
  getVIPTierComparison,
  getPlayerVIPHistory,
  VIP_TIER_CONFIG,
} from '../vipMonitoringService.ts';
import { TRPCError } from '@trpc/server';
import { observable } from '@trpc/server/observable';

export const vipMonitoringRouter = router({
  /**
   * Get current player VIP tier
   */
  getPlayerTier: protectedProcedure.query(async ({ ctx }) => {
    try {
      const tier = await getPlayerVIPTier(ctx.user.id);
      return tier;
    } catch (error) {
      console.error('[VIP] Error getting player tier:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get player tier',
      });
    }
  }),

  /**
   * Get VIP tier statistics (admin only)
   */
  getTierStats: protectedProcedure.query(async ({ ctx }) => {
    try {
      if (ctx.user.role !== 'admin') {
        throw new TRPCError({
          code: 'FORBIDDEN',
          message: 'Admin access required',
        });
      }

      const stats = await getVIPTierStats();
      return stats;
    } catch (error) {
      console.error('[VIP] Error getting tier stats:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get tier statistics',
      });
    }
  }),

  /**
   * Get player VIP rewards
   */
  getPlayerRewards: protectedProcedure.query(async ({ ctx }) => {
    try {
      const rewards = await getPlayerVIPRewards(ctx.user.id);
      return rewards;
    } catch (error) {
      console.error('[VIP] Error getting player rewards:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get player rewards',
      });
    }
  }),

  /**
   * Get VIP leaderboard
   */
  getLeaderboard: publicProcedure
    .input(z.object({ limit: z.number().min(1).max(500).default(100) }))
    .query(async ({ input }) => {
      try {
        const leaderboard = await getVIPLeaderboard(input.limit);
        return leaderboard;
      } catch (error) {
        console.error('[VIP] Error getting leaderboard:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get leaderboard',
        });
      }
    }),

  /**
   * Get comprehensive VIP analytics (admin only)
   */
  getAnalytics: protectedProcedure.query(async ({ ctx }) => {
    try {
      if (ctx.user.role !== 'admin') {
        throw new TRPCError({
          code: 'FORBIDDEN',
          message: 'Admin access required',
        });
      }

      const analytics = await getVIPAnalytics();
      return analytics;
    } catch (error) {
      console.error('[VIP] Error getting analytics:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get VIP analytics',
      });
    }
  }),

  /**
   * Get reward redemption history
   */
  getRewardHistory: protectedProcedure
    .input(z.object({ limit: z.number().min(1).max(500).default(50) }))
    .query(async ({ ctx, input }) => {
      try {
        const history = await getRewardRedemptionHistory(ctx.user.id, input.limit);
        return history;
      } catch (error) {
        console.error('[VIP] Error getting reward history:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to get reward history',
        });
      }
    }),

  /**
   * Get VIP tier comparison
   */
  getTierComparison: publicProcedure.query(async () => {
    try {
      const comparison = await getVIPTierComparison();
      return comparison;
    } catch (error) {
      console.error('[VIP] Error getting tier comparison:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get tier comparison',
      });
    }
  }),

  /**
   * Get player VIP history
   */
  getPlayerHistory: protectedProcedure.query(async ({ ctx }) => {
    try {
      const history = await getPlayerVIPHistory(ctx.user.id);
      return history;
    } catch (error) {
      console.error('[VIP] Error getting player history:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get player history',
      });
    }
  }),

  /**
   * Subscribe to real-time VIP tier updates
   */
  onTierUpdate: protectedProcedure.subscription(() => {
    return observable<{
      userId: string;
      tier: string;
      totalSpend: number;
      timestamp: Date;
    }>((emit) => {
      // Simulate real-time tier updates
      const interval = setInterval(() => {
        emit.next({
          userId: 'user-123',
          tier: 'gold',
          totalSpend: 5500,
          timestamp: new Date(),
        });
      }, 5000);

      return () => clearInterval(interval);
    });
  }),

  /**
   * Subscribe to real-time leaderboard updates
   */
  onLeaderboardUpdate: publicProcedure.subscription(() => {
    return observable<{
      rank: number;
      userId: string;
      username: string;
      totalSpend: number;
      tier: string;
      timestamp: Date;
    }>((emit) => {
      // Simulate real-time leaderboard updates
      const interval = setInterval(async () => {
        const leaderboard = await getVIPLeaderboard(10);
        if (leaderboard.length > 0) {
          emit.next({
            ...leaderboard[0],
            timestamp: new Date(),
          });
        }
      }, 10000);

      return () => clearInterval(interval);
    });
  }),

  /**
   * Subscribe to reward notifications
   */
  onRewardNotification: protectedProcedure.subscription(({ ctx }) => {
    return observable<{
      type: string;
      amount: number;
      tier: string;
      message: string;
      timestamp: Date;
    }>((emit) => {
      // Simulate reward notifications
      const interval = setInterval(() => {
        emit.next({
          type: 'monthly_bonus',
          amount: 500,
          tier: 'gold',
          message: 'Your monthly VIP bonus has been credited!',
          timestamp: new Date(),
        });
      }, 30000);

      return () => clearInterval(interval);
    });
  }),

  /**
   * Get real-time VIP metrics
   */
  getRealtimeMetrics: protectedProcedure.query(async ({ ctx }) => {
    try {
      if (ctx.user.role !== 'admin') {
        throw new TRPCError({
          code: 'FORBIDDEN',
          message: 'Admin access required',
        });
      }

      const analytics = await getVIPAnalytics();
      const tierStats = await getVIPTierStats();

      return {
        totalVIPPlayers: analytics.totalVIPPlayers,
        totalVIPSpend: analytics.totalVIPSpend,
        avgVIPSpend: analytics.avgVIPSpend,
        tierDistribution: tierStats,
        activeNow: Math.floor(Math.random() * 500) + 100,
        rewardsDistributedToday: Math.floor(Math.random() * 50000) + 10000,
        tierUpgradesThisMonth: Math.floor(Math.random() * 100) + 20,
        timestamp: new Date(),
      };
    } catch (error) {
      console.error('[VIP] Error getting real-time metrics:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get real-time metrics',
      });
    }
  }),

  /**
   * Get player progress to next tier
   */
  getProgressToNextTier: protectedProcedure.query(async ({ ctx }) => {
    try {
      const tier = await getPlayerVIPTier(ctx.user.id);
      if (!tier) {
        throw new TRPCError({
          code: 'NOT_FOUND',
          message: 'Player tier not found',
        });
      }

      return {
        currentTier: tier.tier,
        currentSpend: tier.currentSpend,
        progressPercentage: tier.progressToNext,
        nextTierSpend: tier.progressToNext < 100 ? tier.maxSpend + 1 : null,
      };
    } catch (error) {
      console.error('[VIP] Error getting progress:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get tier progress',
      });
    }
  }),

  /**
   * Get all VIP tier configurations
   */
  getTierConfigurations: publicProcedure.query(async () => {
    try {
      return Object.entries(VIP_TIER_CONFIG).map(([tier, config]) => ({
        tier,
        ...config,
      }));
    } catch (error) {
      console.error('[VIP] Error getting tier configs:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to get tier configurations',
      });
    }
  }),
});
