import { router, protectedProcedure, publicProcedure } from './trpc';
import { z } from 'zod';
import { leaderboardFilterService, TimePeriod } from './leaderboardFilterService';
import { achievementUnlockSystem } from './achievementUnlockSystem';
import { socialSharingAnalytics } from './socialSharingAnalytics';
import { shareRewardsSystem } from './shareRewardsSystem';
import { milestoneDetectionSystem } from './milestoneDetectionSystem';

/**
 * Leaderboards Router
 */
export const leaderboardsRouter = router({
  // Get filtered leaderboard
  getLeaderboard: publicProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
        gameId: z.string().optional(),
        limit: z.number().min(1).max(100).default(50),
      })
    )
    .query(({ input }) => {
      return leaderboardFilterService.getLeaderboard({
        period: input.period as TimePeriod,
        gameId: input.gameId,
        limit: input.limit,
      });
    }),

  // Get top players
  getTopPlayers: publicProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
        limit: z.number().min(1).max(50).default(10),
      })
    )
    .query(({ input }) => {
      return leaderboardFilterService.getTopPlayers(input.period as TimePeriod, input.limit);
    }),

  // Get player's global rank
  getPlayerGlobalRank: publicProcedure
    .input(
      z.object({
        userId: z.string(),
        period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
      })
    )
    .query(({ input }) => {
      return leaderboardFilterService.getPlayerGlobalRank(input.userId, input.period as TimePeriod);
    }),

  // Get leaderboard statistics
  getStats: publicProcedure
    .input(z.object({ period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const) }))
    .query(({ input }) => {
      return leaderboardFilterService.getLeaderboardStats(input.period as TimePeriod);
    }),

  // Get nearby competitors
  getNearbyCompetitors: publicProcedure
    .input(
      z.object({
        userId: z.string(),
        period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
        range: z.number().min(1).max(10).default(5),
      })
    )
    .query(({ input }) => {
      return leaderboardFilterService.getNearbyCompetitors(input.userId, input.period as TimePeriod, input.range);
    }),

  // Get trending players
  getTrendingPlayers: publicProcedure
    .input(
      z.object({
        period: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
        previousPeriod: z.enum(['daily', 'weekly', 'monthly', 'all-time'] as const),
        limit: z.number().min(1).max(50).default(10),
      })
    )
    .query(({ input }) => {
      return leaderboardFilterService.getTrendingPlayers(
        input.period as TimePeriod,
        input.previousPeriod as TimePeriod,
        input.limit
      );
    }),
});

/**
 * Achievements Router
 */
export const achievementsRouter = router({
  // Get user's unlocked achievements
  getUnlocks: protectedProcedure.query(({ ctx }) => {
    return achievementUnlockSystem.getUserUnlocks(ctx.user.id);
  }),

  // Record an achievement unlock
  recordUnlock: protectedProcedure
    .input(
      z.object({
        achievementId: z.string(),
        name: z.string(),
        description: z.string(),
        icon: z.string(),
        rarity: z.enum(['common', 'rare', 'epic', 'legendary']),
        reward: z
          .object({
            coins: z.number().optional(),
            xp: z.number().optional(),
            badge: z.string().optional(),
          })
          .optional(),
      })
    )
    .mutation(({ ctx, input }) => {
      return achievementUnlockSystem.recordUnlock(ctx.user.id, {
        id: input.achievementId,
        name: input.name,
        description: input.description,
        icon: input.icon,
        rarity: input.rarity,
        reward: input.reward,
      });
    }),

  // Get user's milestones
  getMilestones: protectedProcedure.query(({ ctx }) => {
    return achievementUnlockSystem.getUserMilestones(ctx.user.id);
  }),

  // Get achievement statistics
  getStats: protectedProcedure.query(({ ctx }) => {
    return achievementUnlockSystem.getUnlockStats();
  }),

  // Get most shared achievements
  getMostShared: publicProcedure
    .input(z.object({ limit: z.number().min(1).max(50).default(10) }))
    .query(({ input }) => {
      return achievementUnlockSystem.getMostSharedAchievements(input.limit);
    }),

  // Check if user has unlocked achievement
  hasUnlocked: protectedProcedure
    .input(z.object({ achievementId: z.string() }))
    .query(({ ctx, input }) => {
      return achievementUnlockSystem.hasUnlocked(ctx.user.id, input.achievementId);
    }),
});

/**
 * Social Sharing Router
 */
export const socialSharingRouter = router({
  // Record a share
  recordShare: protectedProcedure
    .input(
      z.object({
        shareableId: z.string(),
        shareableType: z.enum(['achievement', 'score', 'milestone', 'tournament']),
        platform: z.enum(['twitter', 'facebook', 'discord', 'link', 'image']),
      })
    )
    .mutation(({ ctx, input }) => {
      socialSharingAnalytics.recordShare({
        userId: ctx.user.id,
        shareableId: input.shareableId,
        shareableType: input.shareableType,
        platform: input.platform,
        timestamp: new Date(),
      });

      // Award share reward
      const reward = shareRewardsSystem.recordShareReward(ctx.user.id, input.shareableId, input.platform);

      return reward;
    }),

  // Get sharing metrics
  getMetrics: publicProcedure.query(() => {
    return socialSharingAnalytics.getMetrics();
  }),

  // Get user's sharing statistics
  getUserStats: protectedProcedure.query(({ ctx }) => {
    return socialSharingAnalytics.getUserShareStats(ctx.user.id);
  }),

  // Track a click on shared content
  trackClick: publicProcedure
    .input(
      z.object({
        shareableId: z.string(),
        platform: z.enum(['twitter', 'facebook', 'discord', 'link', 'image']),
      })
    )
    .mutation(({ input }) => {
      socialSharingAnalytics.trackClick(input.shareableId, input.platform);
      return { success: true };
    }),

  // Get engagement metrics
  getEngagement: publicProcedure.query(() => {
    return socialSharingAnalytics.getEngagementMetrics();
  }),

  // Get trending shares
  getTrending: publicProcedure
    .input(z.object({ hours: z.number().min(1).max(168).default(24) }))
    .query(({ input }) => {
      return socialSharingAnalytics.getTrendingShares(input.hours);
    }),

  // Get platform-specific metrics
  getPlatformMetrics: publicProcedure
    .input(z.object({ platform: z.enum(['twitter', 'facebook', 'discord', 'link', 'image']) }))
    .query(({ input }) => {
      return socialSharingAnalytics.getPlatformMetrics(input.platform);
    }),
});

/**
 * Share Rewards Router
 */
export const shareRewardsRouter = router({
  // Record a share and award reward
  recordShareReward: protectedProcedure
    .input(
      z.object({
        shareId: z.string(),
        platform: z.string(),
      })
    )
    .mutation(({ ctx, input }) => {
      return shareRewardsSystem.recordShareReward(ctx.user.id, input.shareId, input.platform);
    }),

  // Get today's share stats
  getTodayStats: protectedProcedure.query(({ ctx }) => {
    return shareRewardsSystem.getTodayStats(ctx.user.id);
  }),

  // Get total share rewards
  getTotalRewards: protectedProcedure.query(({ ctx }) => {
    return shareRewardsSystem.getTotalShareRewards(ctx.user.id);
  }),

  // Get user's share reward statistics
  getStats: protectedProcedure.query(({ ctx }) => {
    return shareRewardsSystem.getShareRewardStats(ctx.user.id);
  }),

  // Get daily progress
  getDailyProgress: protectedProcedure.query(({ ctx }) => {
    return shareRewardsSystem.getDailyProgress(ctx.user.id);
  }),

  // Check if user can share today
  canShareToday: protectedProcedure.query(({ ctx }) => {
    return shareRewardsSystem.canShareToday(ctx.user.id);
  }),

  // Get top share reward earners
  getTopEarners: publicProcedure
    .input(z.object({ limit: z.number().min(1).max(50).default(10) }))
    .query(({ input }) => {
      return shareRewardsSystem.getTopEarners(input.limit);
    }),

  // Get global share reward statistics
  getGlobalStats: publicProcedure.query(() => {
    return shareRewardsSystem.getGlobalStats();
  }),
});

/**
 * Milestones Router
 */
export const milestonesRouter = router({
  // Check level milestone
  checkLevelMilestone: protectedProcedure
    .input(
      z.object({
        newLevel: z.number().min(1),
        previousLevel: z.number().min(0).default(0),
      })
    )
    .mutation(({ ctx, input }) => {
      return milestoneDetectionSystem.checkLevelMilestone(ctx.user.id, input.newLevel, input.previousLevel);
    }),

  // Check win milestone
  checkWinMilestone: protectedProcedure
    .input(
      z.object({
        newWins: z.number().min(0),
        previousWins: z.number().min(0).default(0),
      })
    )
    .mutation(({ ctx, input }) => {
      return milestoneDetectionSystem.checkWinMilestone(ctx.user.id, input.newWins, input.previousWins);
    }),

  // Check score milestone
  checkScoreMilestone: protectedProcedure
    .input(
      z.object({
        newScore: z.number().min(0),
        previousScore: z.number().min(0).default(0),
      })
    )
    .mutation(({ ctx, input }) => {
      return milestoneDetectionSystem.checkScoreMilestone(ctx.user.id, input.newScore, input.previousScore);
    }),

  // Get user's milestones
  getUserMilestones: protectedProcedure.query(({ ctx }) => {
    return milestoneDetectionSystem.getUserMilestones(ctx.user.id);
  }),

  // Get next milestone
  getNextMilestone: protectedProcedure
    .input(z.object({ type: z.enum(['level', 'wins', 'score', 'streak']) }))
    .query(({ ctx, input }) => {
      return milestoneDetectionSystem.getNextMilestone(ctx.user.id, input.type as any);
    }),

  // Get progress to next milestone
  getProgress: protectedProcedure
    .input(z.object({ type: z.enum(['level', 'wins', 'score', 'streak']) }))
    .query(({ ctx, input }) => {
      return milestoneDetectionSystem.getProgressToNextMilestone(ctx.user.id, input.type as any);
    }),

  // Get upcoming milestones
  getUpcoming: protectedProcedure
    .input(z.object({ limit: z.number().min(1).max(10).default(5) }))
    .query(({ ctx, input }) => {
      return milestoneDetectionSystem.getUpcomingMilestones(ctx.user.id, input.limit);
    }),

  // Get milestone statistics
  getStats: protectedProcedure.query(({ ctx }) => {
    return milestoneDetectionSystem.getMilestoneStats(ctx.user.id);
  }),
});
