import { router, protectedProcedure } from '../_core/trpc.js.ts';
import { z } from 'zod';
import NotificationSchedulingService from '../notificationSchedulingService.js';

const schedulingService = new NotificationSchedulingService();

export const notificationSchedulingRouter = router({
  /**
   * Schedule notification
   */
  scheduleNotification: protectedProcedure
    .input(
      z.object({
        campaignId: z.string(),
        title: z.string(),
        message: z.string(),
        scheduledFor: z.date(),
        timezone: z.string().optional(),
        recurring: z
          .object({
            pattern: z.enum(['daily', 'weekly', 'monthly']),
            endDate: z.date().optional(),
            daysOfWeek: z.array(z.number()).optional(),
          })
          .optional(),
      })
    )
    .mutation(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.scheduleNotification(
        input.campaignId,
        input.title,
        input.message,
        input.scheduledFor,
        {
          timezone: input.timezone,
          recurring: input.recurring,
        }
      );
    }),

  /**
   * Check scheduling conflicts
   */
  checkConflicts: protectedProcedure
    .input(z.object({ scheduledFor: z.date() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.checkSchedulingConflicts(input.scheduledFor);
    }),

  /**
   * Get available time slots
   */
  getAvailableTimeSlots: protectedProcedure
    .input(z.object({ date: z.date() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getAvailableTimeSlots(input.date);
    }),

  /**
   * Reschedule notification
   */
  rescheduleNotification: protectedProcedure
    .input(z.object({ notificationId: z.string(), newScheduledFor: z.date() }))
    .mutation(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.rescheduleNotification(input.notificationId, input.newScheduledFor);
    }),

  /**
   * Cancel notification
   */
  cancelNotification: protectedProcedure
    .input(z.object({ notificationId: z.string() }))
    .mutation(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.cancelNotification(input.notificationId);
    }),

  /**
   * Get calendar events
   */
  getCalendarEvents: protectedProcedure
    .input(z.object({ startDate: z.date(), endDate: z.date() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getCalendarEvents(input.startDate, input.endDate);
    }),

  /**
   * Get notifications for date
   */
  getNotificationsForDate: protectedProcedure
    .input(z.object({ date: z.date() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getNotificationsForDate(input.date);
    }),

  /**
   * Get upcoming notifications
   */
  getUpcomingNotifications: protectedProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getUpcomingNotifications(input.limit);
    }),

  /**
   * Get notifications by campaign
   */
  getNotificationsByCampaign: protectedProcedure
    .input(z.object({ campaignId: z.string() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getNotificationsByCampaign(input.campaignId);
    }),

  /**
   * Get scheduling statistics
   */
  getSchedulingStatistics: protectedProcedure
    .input(z.object({ startDate: z.date().optional(), endDate: z.date().optional() }))
    .query(({ input, ctx }) => {
      // Check if user is admin
      if (ctx.user.role !== 'admin') {
        throw new Error('Unauthorized');
      }

      return schedulingService.getSchedulingStatistics(input.startDate, input.endDate);
    }),

  /**
   * Get optimal send times
   */
  getOptimalSendTimes: protectedProcedure.query(({ ctx }) => {
    // Check if user is admin
    if (ctx.user.role !== 'admin') {
      throw new Error('Unauthorized');
    }

    return schedulingService.getOptimalSendTimes();
  }),
});

export default notificationSchedulingRouter;
