import { protectedProcedure, publicProcedure, router } from '../_core/trpc.ts';
import { z } from 'zod';
import { pushNotificationsManager } from '../pushNotifications.ts';
import { multiplayerGamesManager } from '../multiplayerGames.ts';
import { streamerIntegrationManager } from '../streamerIntegration.ts';

export const engagementAdvancedRouter = router({
  // ===== PUSH NOTIFICATIONS =====

  // Get user notifications
  getNotifications: protectedProcedure
    .input(z.object({ limit: z.number().default(50) }))
    .query(async ({ ctx, input }) => {
      const notifications = await pushNotificationsManager.getUserNotifications(ctx.user.id, input.limit);
      return notifications;
    }),

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

  // Mark notification as read
  markAsRead: protectedProcedure
    .input(z.object({ notificationId: z.string() }))
    .mutation(async ({ input }) => {
      await pushNotificationsManager.markAsRead(input.notificationId);
      return { success: true };
    }),

  // Mark all as read
  markAllAsRead: protectedProcedure.mutation(async ({ ctx }) => {
    await pushNotificationsManager.markAllAsRead(ctx.user.id);
    return { success: true };
  }),

  // Get notification preferences
  getNotificationPreferences: protectedProcedure.query(async ({ ctx }) => {
    const prefs = await pushNotificationsManager.getUserPreferences(ctx.user.id);
    return prefs;
  }),

  // Update notification preferences
  updateNotificationPreferences: protectedProcedure
    .input(
      z.object({
        achievements: z.boolean().optional(),
        challenges: z.boolean().optional(),
        leaderboard: z.boolean().optional(),
        events: z.boolean().optional(),
        friends: z.boolean().optional(),
        promotions: z.boolean().optional(),
        system: z.boolean().optional(),
        quietHoursEnabled: z.boolean().optional(),
        quietHoursStart: z.string().optional(),
        quietHoursEnd: z.string().optional(),
        pushEnabled: z.boolean().optional(),
        emailEnabled: z.boolean().optional(),
        smsEnabled: z.boolean().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const prefs = await pushNotificationsManager.updatePreferences(ctx.user.id, input);
      return prefs;
    }),

  // ===== MULTIPLAYER GAMES =====

  // Get active games
  getActiveGames: publicProcedure.query(async () => {
    const games = await multiplayerGamesManager.getActiveGames();
    return games;
  }),

  // Get games by type
  getGamesByType: publicProcedure
    .input(z.object({ type: z.enum(['slots_tournament', 'spinning_race', 'daily_battle', 'team_challenge']) }))
    .query(async ({ input }) => {
      const games = await multiplayerGamesManager.getGamesByType(input.type);
      return games;
    }),

  // Join game
  joinGame: protectedProcedure
    .input(z.object({ gameId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const result = await multiplayerGamesManager.joinGame(ctx.user.id, ctx.user.name, input.gameId);
      return result;
    }),

  // Get game details
  getGame: publicProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const game = await multiplayerGamesManager.getGame(input.gameId);
      return game;
    }),

  // Get game participants
  getGameParticipants: publicProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const participants = await multiplayerGamesManager.getGameParticipants(input.gameId);
      return participants;
    }),

  // Get game leaderboard
  getGameLeaderboard: publicProcedure
    .input(z.object({ gameId: z.string() }))
    .query(async ({ input }) => {
      const leaderboard = await multiplayerGamesManager.getGameLeaderboard(input.gameId);
      return leaderboard;
    }),

  // Get player's games
  getPlayerGames: protectedProcedure.query(async ({ ctx }) => {
    const games = await multiplayerGamesManager.getPlayerGames(ctx.user.id);
    return games;
  }),

  // Update game score (internal use)
  updateGameScore: protectedProcedure
    .input(z.object({ gameId: z.string(), scoreIncrement: z.number() }))
    .mutation(async ({ ctx, input }) => {
      await multiplayerGamesManager.updateScore(ctx.user.id, input.gameId, input.scoreIncrement);
      return { success: true };
    }),

  // Get multiplayer games stats
  getMultiplayerStats: publicProcedure.query(async () => {
    const stats = await multiplayerGamesManager.getStats();
    return stats;
  }),

  // ===== STREAMER INTEGRATION =====

  // Register as streamer
  registerAsStreamer: protectedProcedure
    .input(z.object({ displayName: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const profile = await streamerIntegrationManager.registerStreamer(ctx.user.id, ctx.user.name, input.displayName);
      return profile;
    }),

  // Get streamer profile
  getStreamerProfile: publicProcedure
    .input(z.object({ userId: z.number() }))
    .query(async ({ input }) => {
      const profile = await streamerIntegrationManager.getStreamerProfile(input.userId);
      return profile;
    }),

  // Get my streamer profile
  getMyStreamerProfile: protectedProcedure.query(async ({ ctx }) => {
    const profile = await streamerIntegrationManager.getStreamerProfile(ctx.user.id);
    return profile;
  }),

  // Update streamer profile
  updateStreamerProfile: protectedProcedure
    .input(
      z.object({
        displayName: z.string().optional(),
        bio: z.string().optional(),
        twitchHandle: z.string().optional(),
        youtubeHandle: z.string().optional(),
        discordHandle: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const profile = await streamerIntegrationManager.updateStreamerProfile(ctx.user.id, input);
      return profile;
    }),

  // Start stream session
  startStreamSession: protectedProcedure
    .input(
      z.object({
        title: z.string(),
        platform: z.enum(['twitch', 'youtube', 'other']),
        streamUrl: z.string().optional(),
        description: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const session = await streamerIntegrationManager.startStreamSession(
        ctx.user.id,
        input.title,
        input.platform,
        input.streamUrl,
        input.description
      );
      return session;
    }),

  // Update stream stats
  updateStreamStats: protectedProcedure
    .input(z.object({ sessionId: z.string(), viewerCount: z.number(), engagement: z.number() }))
    .mutation(async ({ input }) => {
      await streamerIntegrationManager.updateStreamStats(input.sessionId, input.viewerCount, input.engagement);
      return { success: true };
    }),

  // End stream session
  endStreamSession: protectedProcedure
    .input(z.object({ sessionId: z.string() }))
    .mutation(async ({ input }) => {
      const session = await streamerIntegrationManager.endStreamSession(input.sessionId);
      return session;
    }),

  // Get streamer dashboard
  getStreamerDashboard: protectedProcedure.query(async ({ ctx }) => {
    const dashboard = await streamerIntegrationManager.getStreamerDashboard(ctx.user.id);
    return dashboard;
  }),

  // Get top streamers
  getTopStreamers: publicProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(async ({ input }) => {
      const streamers = await streamerIntegrationManager.getTopStreamers(input.limit);
      return streamers;
    }),

  // Get streamer stats
  getStreamerStats: publicProcedure.query(async () => {
    const stats = await streamerIntegrationManager.getStats();
    return stats;
  }),

  // Get notification stats (admin)
  getNotificationStats: protectedProcedure.query(async ({ ctx }) => {
    if (ctx.user.role !== 'admin') {
      throw new Error('Unauthorized');
    }

    const stats = await pushNotificationsManager.getStats();
    return stats;
  }),
});
