import { protectedProcedure, publicProcedure, router } from "../_core/trpc.ts";
import { z } from "zod";
import { chatManager } from "../chat.ts";
import { achievementManager } from "../achievements.ts";
import { dailyChallengesManager } from "../dailyChallenges.ts";

export const engagementRouter = router({
  // ===== CHAT PROCEDURES =====

  // Send message
  sendMessage: protectedProcedure
    .input(z.object({ recipientId: z.number(), content: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const message = await chatManager.sendMessage(
        ctx.user.id,
        ctx.user.name,
        input.recipientId,
        input.content
      );
      return message;
    }),

  // Get conversation messages
  getMessages: protectedProcedure
    .input(z.object({ userId: z.number(), limit: z.number().default(50) }))
    .query(async ({ ctx, input }) => {
      const messages = await chatManager.getMessages(ctx.user.id, input.userId, input.limit);
      return messages;
    }),

  // Get conversations
  getConversations: protectedProcedure.query(async ({ ctx }) => {
    const conversations = await chatManager.getUserConversations(ctx.user.id);
    return conversations;
  }),

  // Get unread count
  getUnreadCount: protectedProcedure.query(async ({ ctx }) => {
    const count = await chatManager.getUnreadCount(ctx.user.id);
    return { unreadCount: count };
  }),

  // Mark message as read
  markAsRead: protectedProcedure
    .input(z.object({ messageId: z.string(), conversationId: z.string() }))
    .mutation(async ({ input }) => {
      await chatManager.markAsRead(input.messageId, input.conversationId);
      return { success: true };
    }),

  // Mark conversation as read
  markConversationAsRead: protectedProcedure
    .input(z.object({ conversationId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      await chatManager.markConversationAsRead(ctx.user.id, input.conversationId);
      return { success: true };
    }),

  // Get user status
  getUserStatus: publicProcedure
    .input(z.object({ userId: z.number() }))
    .query(async ({ input }) => {
      const status = await chatManager.getUserStatus(input.userId);
      return status;
    }),

  // Get multiple users' status
  getUsersStatus: publicProcedure
    .input(z.object({ userIds: z.array(z.number()) }))
    .query(async ({ input }) => {
      const statuses = await chatManager.getUsersStatus(input.userIds);
      return statuses;
    }),

  // ===== ACHIEVEMENT PROCEDURES =====

  // Get player achievements
  getAchievements: protectedProcedure.query(async ({ ctx }) => {
    const achievements = await achievementManager.getPlayerAchievements(ctx.user.id);
    return achievements;
  }),

  // Get unlocked achievements
  getUnlockedAchievements: protectedProcedure.query(async ({ ctx }) => {
    const achievements = await achievementManager.getUnlockedAchievements(ctx.user.id);
    return achievements;
  }),

  // Get achievement progress
  getAchievementProgress: protectedProcedure
    .input(z.object({ achievementId: z.string() }))
    .query(async ({ ctx, input }) => {
      const progress = await achievementManager.getAchievementProgress(ctx.user.id, input.achievementId);
      return progress;
    }),

  // Get all achievements
  getAllAchievements: publicProcedure.query(async () => {
    const achievements = achievementManager.getAllAchievements();
    return achievements;
  }),

  // Get achievements by category
  getAchievementsByCategory: publicProcedure
    .input(z.object({ category: z.enum(['gameplay', 'social', 'spending', 'milestone', 'special']) }))
    .query(async ({ input }) => {
      const achievements = achievementManager.getAchievementsByCategory(input.category);
      return achievements;
    }),

  // Get player achievement stats
  getAchievementStats: protectedProcedure.query(async ({ ctx }) => {
    const stats = await achievementManager.getPlayerStats(ctx.user.id);
    return stats;
  }),

  // ===== DAILY CHALLENGES PROCEDURES =====

  // Get today's challenges
  getTodaysChallenges: publicProcedure.query(async () => {
    const challenges = await dailyChallengesManager.getTodaysChallenges();
    return challenges;
  }),

  // Get player challenges
  getPlayerChallenges: protectedProcedure.query(async ({ ctx }) => {
    const challenges = await dailyChallengesManager.getPlayerChallenges(ctx.user.id);
    return challenges;
  }),

  // Initialize player challenges
  initializeChallenges: protectedProcedure.mutation(async ({ ctx }) => {
    await dailyChallengesManager.initializePlayerChallenges(ctx.user.id);
    return { success: true };
  }),

  // Claim challenge reward
  claimChallengeReward: protectedProcedure
    .input(z.object({ challengeId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const result = await dailyChallengesManager.claimReward(ctx.user.id, input.challengeId);
      return result;
    }),

  // Get challenge stats
  getChallengeStats: protectedProcedure.query(async ({ ctx }) => {
    const stats = await dailyChallengesManager.getPlayerStats(ctx.user.id);
    return stats;
  }),

  // Get all challenges
  getAllChallenges: publicProcedure.query(async () => {
    const challenges = dailyChallengesManager.getAllChallenges();
    return challenges;
  }),

  // Get challenges by difficulty
  getChallengesByDifficulty: publicProcedure
    .input(z.object({ difficulty: z.enum(['easy', 'medium', 'hard', 'extreme']) }))
    .query(async ({ input }) => {
      const challenges = dailyChallengesManager.getChallengesByDifficulty(input.difficulty);
      return challenges;
    }),

  // ===== COMBINED STATS =====

  // Get all engagement stats
  getEngagementStats: protectedProcedure.query(async ({ ctx }) => {
    const achievementStats = await achievementManager.getPlayerStats(ctx.user.id);
    const challengeStats = await dailyChallengesManager.getPlayerStats(ctx.user.id);
    const unreadCount = await chatManager.getUnreadCount(ctx.user.id);

    return {
      achievements: achievementStats,
      challenges: challengeStats,
      chat: { unreadCount },
    };
  }),
});
