import { prisma } from "@capakraken/db";
import { emitReminderDue, emitNotificationCreated } from "../sse/event-bus.js";

const POLL_INTERVAL_MS = 60_000; // 60 seconds

function computeNextRemindAt(current: Date, recurrence: string): Date {
  const next = new Date(current);
  switch (recurrence) {
    case "daily":
      next.setDate(next.getDate() + 1);
      break;
    case "weekly":
      next.setDate(next.getDate() + 7);
      break;
    case "monthly":
      next.setMonth(next.getMonth() + 1);
      break;
    default:
      return current;
  }
  return next;
}

async function processReminders() {
  const now = new Date();

  // Find all due reminders
  const dueReminders = await prisma.notification.findMany({
    where: {
      category: "REMINDER",
      nextRemindAt: { lte: now },
    },
    take: 100, // process in batches
  });

  for (const reminder of dueReminders) {
    try {
      if (reminder.recurrence) {
        // Recurring: create a new notification for this occurrence, advance nextRemindAt
        const notification = await prisma.notification.create({
          data: {
            userId: reminder.userId,
            category: "NOTIFICATION",
            type: "REMINDER_DUE",
            priority: reminder.priority,
            title: reminder.title,
            body: reminder.body,
            entityId: reminder.entityId,
            entityType: reminder.entityType,
            link: reminder.link,
            sourceId: reminder.id,
            channel: "in_app",
          },
        });

        // Advance to next occurrence
        await prisma.notification.update({
          where: { id: reminder.id },
          data: {
            nextRemindAt: computeNextRemindAt(reminder.nextRemindAt!, reminder.recurrence),
          },
        });

        emitNotificationCreated(reminder.userId, notification.id);
        emitReminderDue(reminder.userId, notification.id);
      } else {
        // One-shot: mark the reminder as "fired" by clearing nextRemindAt
        await prisma.notification.update({
          where: { id: reminder.id },
          data: { nextRemindAt: null },
        });

        emitReminderDue(reminder.userId, reminder.id);
        emitNotificationCreated(reminder.userId, reminder.id);
      }
    } catch (err) {
      console.error(`[ReminderScheduler] Error processing reminder ${reminder.id}:`, err);
    }
  }
}

let intervalId: ReturnType<typeof setInterval> | null = null;

export function startReminderScheduler(): void {
  if (intervalId) return; // already running
  console.log("[ReminderScheduler] Starting (poll every 60s)");
  // Run immediately to catch up on overdue reminders
  void processReminders();
  intervalId = setInterval(() => void processReminders(), POLL_INTERVAL_MS);
}

export function stopReminderScheduler(): void {
  if (intervalId) {
    clearInterval(intervalId);
    intervalId = null;
    console.log("[ReminderScheduler] Stopped");
  }
}
