import { z } from 'zod';
import { protectedProcedure, router } from "../_core/trpc.ts";
import { TRPCError } from '@trpc/server';
import {
  sendEventStartNotification,
  sendEventEndingNotification,
  sendRewardNotification,
  sendMilestoneNotification,
  sendReminderNotification,
  getUserNotificationPreferences,
  updateNotificationPreferences,
  getUnreadNotifications,
  markNotificationAsRead,
} from "../services/eventNotifications.ts";

export const seasonalEventsNotificationsRouter = router({
  // Get user notification preferences
  getPreferences: protectedProcedure.query(async ({ ctx }) => {
    const preferences = await getUserNotificationPreferences(ctx.user.id);
    return preferences;
  }),

  // Update notification preferences
  updatePreferences: protectedProcedure
    .input(
      z.object({
        eventStartNotifications: z.boolean().optional(),
        eventEndingNotifications: z.boolean().optional(),
        rewardNotifications: z.boolean().optional(),
        milestoneNotifications: z.boolean().optional(),
        reminderNotifications: z.boolean().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const success = await updateNotificationPreferences(ctx.user.id, input);
      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to update preferences',
        });
      }
      return { success: true, message: 'Preferences updated' };
    }),

  // Get unread notifications
  getUnread: protectedProcedure.query(async ({ ctx }) => {
    const notifications = await getUnreadNotifications(ctx.user.id);
    return {
      count: notifications.length,
      notifications,
    };
  }),

  // Mark notification as read
  markAsRead: protectedProcedure
    .input(z.object({ notificationId: z.string() }))
    .mutation(async ({ input, ctx }) => {
      const success = await markNotificationAsRead(input.notificationId);
      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to mark notification as read',
        });
      }
      return { success: true };
    }),

  // Send event start notification (admin only)
  sendEventStart: protectedProcedure
    .input(z.object({ eventId: z.string(), theme: z.string(), userId: z.number().optional() }))
    .mutation(async ({ input, ctx }) => {
      if (ctx.user.role !== 'admin') {
        throw new TRPCError({ code: 'FORBIDDEN', message: 'Admin only' });
      }

      const userId = input.userId || ctx.user.id;
      const success = await sendEventStartNotification(userId, input.eventId, input.theme);

      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send notification',
        });
      }

      return { success: true, message: 'Event start notification sent' };
    }),

  // Send event ending notification (admin only)
  sendEventEnding: protectedProcedure
    .input(z.object({ eventId: z.string(), theme: z.string(), userId: z.number().optional() }))
    .mutation(async ({ input, ctx }) => {
      if (ctx.user.role !== 'admin') {
        throw new TRPCError({ code: 'FORBIDDEN', message: 'Admin only' });
      }

      const userId = input.userId || ctx.user.id;
      const success = await sendEventEndingNotification(userId, input.eventId, input.theme);

      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send notification',
        });
      }

      return { success: true, message: 'Event ending notification sent' };
    }),

  // Send reward notification
  sendReward: protectedProcedure
    .input(z.object({ eventId: z.string(), rewardName: z.string() }))
    .mutation(async ({ input, ctx }) => {
      const success = await sendRewardNotification(ctx.user.id, input.eventId, input.rewardName);

      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send notification',
        });
      }

      return { success: true, message: 'Reward notification sent' };
    }),

  // Send milestone notification
  sendMilestone: protectedProcedure
    .input(z.object({ eventId: z.string(), milestone: z.number() }))
    .mutation(async ({ input, ctx }) => {
      const success = await sendMilestoneNotification(ctx.user.id, input.eventId, input.milestone);

      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send notification',
        });
      }

      return { success: true, message: 'Milestone notification sent' };
    }),

  // Send reminder notification
  sendReminder: protectedProcedure
    .input(z.object({ eventId: z.string() }))
    .mutation(async ({ input, ctx }) => {
      const success = await sendReminderNotification(ctx.user.id, input.eventId);

      if (!success) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send notification',
        });
      }

      return { success: true, message: 'Reminder notification sent' };
    }),
});
