import { router, protectedProcedure, publicProcedure } from '../_core/trpc.js.ts';
import { z } from 'zod';
import PushNotificationsService from '../pushNotificationsService.js';

const pushNotificationsService = new PushNotificationsService();

export const pushNotificationsRouter = router({
  /**
   * Get user's notifications
   */
  getNotifications: protectedProcedure
    .input(
      z.object({
        limit: z.number().default(50),
        unreadOnly: z.boolean().default(false),
      })
    )
    .query(({ input, ctx }) => {
      return pushNotificationsService.getNotifications(ctx.user.id, input.limit, input.unreadOnly);
    }),

  /**
   * Get unread notification count
   */
  getUnreadCount: protectedProcedure.query(({ ctx }) => {
    return pushNotificationsService.getUnreadCount(ctx.user.id);
  }),

  /**
   * Mark notification as read
   */
  markAsRead: protectedProcedure
    .input(z.object({ notificationId: z.string() }))
    .mutation(({ input, ctx }) => {
      const success = pushNotificationsService.markAsRead(ctx.user.id, input.notificationId);
      return { success };
    }),

  /**
   * Mark all notifications as read
   */
  markAllAsRead: protectedProcedure.mutation(({ ctx }) => {
    const count = pushNotificationsService.markAllAsRead(ctx.user.id);
    return { count };
  }),

  /**
   * Get notification preferences
   */
  getPreferences: protectedProcedure.query(({ ctx }) => {
    return pushNotificationsService.getPreferences(ctx.user.id);
  }),

  /**
   * Update notification preferences
   */
  updatePreferences: protectedProcedure
    .input(
      z.object({
        shareRewards: z.boolean().optional(),
        achievements: z.boolean().optional(),
        tierUps: z.boolean().optional(),
        tournaments: z.boolean().optional(),
        games: z.boolean().optional(),
        system: z.boolean().optional(),
        channels: z
          .object({
            push: z.boolean().optional(),
            email: z.boolean().optional(),
            inApp: z.boolean().optional(),
          })
          .optional(),
      })
    )
    .mutation(({ input, ctx }) => {
      return pushNotificationsService.updatePreferences(ctx.user.id, input as any);
    }),

  /**
   * Subscribe to notifications
   */
  subscribe: protectedProcedure
    .input(z.object({ subscriptionId: z.string() }))
    .mutation(({ input, ctx }) => {
      pushNotificationsService.subscribe(ctx.user.id, input.subscriptionId);
      return { success: true };
    }),

  /**
   * Unsubscribe from notifications
   */
  unsubscribe: protectedProcedure
    .input(z.object({ subscriptionId: z.string() }))
    .mutation(({ input, ctx }) => {
      pushNotificationsService.unsubscribe(ctx.user.id, input.subscriptionId);
      return { success: true };
    }),

  /**
   * Subscribe to notification updates
   */
  onNotification: protectedProcedure.subscription(async function* ({ ctx }) {
    const userId = ctx.user.id;

    const handleNotification = (data: any) => {
      if (data.userId === userId) {
        yield data.notification;
      }
    };

    pushNotificationsService.on('in_app_notification', handleNotification);

    try {
      await new Promise(() => {});
    } finally {
      pushNotificationsService.removeListener('in_app_notification', handleNotification);
    }
  }),

  /**
   * Get notification statistics (admin only)
   */
  getStatistics: protectedProcedure.query(({ ctx }) => {
    // Check if user is admin
    if (ctx.user.role !== 'admin') {
      throw new Error('Unauthorized');
    }

    return pushNotificationsService.getStatistics();
  }),

  /**
   * Send test notification (admin only)
   */
  sendTestNotification: protectedProcedure
    .input(
      z.object({
        title: z.string(),
        body: z.string(),
        type: z.enum(['share_reward', 'achievement', 'tier_up', 'tournament', 'game', 'system']),
      })
    )
    .mutation(async ({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return pushNotificationsService.sendNotification(
        ctx.user.id,
        input.title,
        input.body,
        input.type
      );
    }),

  /**
   * Clear old notifications
   */
  clearOldNotifications: protectedProcedure.mutation(({ ctx }) => {
    // Check if user is admin
    if (ctx.user.role !== 'admin') {
      throw new Error('Unauthorized');
    }

    pushNotificationsService.clearOldNotifications();
    return { success: true };
  }),
});

export default pushNotificationsRouter;
