// src/server/features/notes/lib/reminder-worker.service.ts
// Personal reminder worker for checking and triggering note reminders from note_layouts

import { db } from '../../../shared/db/client';
import { noteLayouts } from '../db/note_layouts.table';
import { notes } from '../db/notes.table';
import { eq, and, lt, isNull } from 'drizzle-orm';
import { logger } from '../../../shared/lib/logger';
import { emitEvent } from '../../../shared/lib/events';
import { dayjs } from '../../../shared/lib/dayjs';

/**
 * Note reminder event payload (personal)
 */
export interface PersonalNoteReminderEvent {
  noteId: string;
  title: string;
  userId: string;
  reminderAt: string;
}

/**
 * Check for pending personal reminders and trigger notifications
 * This function should be called by a cron job (e.g., every minute)
 */
export async function checkAndTriggerPersonalReminders(): Promise<void> {
  try {
    logger.info('[ReminderWorker] Checking for pending personal reminders...');

    const now = dayjs().toDate();

    // Find note_layouts with:
    // - reminderAt is set and in the past
    // - note is not archived
    const pendingReminders = await db
      .select({
        layoutId: noteLayouts.id,
        noteId: noteLayouts.noteId,
        userId: noteLayouts.userId,
        reminderAt: noteLayouts.reminderAt,
        noteTitle: notes.title,
      })
      .from(noteLayouts)
      .innerJoin(notes, eq(noteLayouts.noteId, notes.id))
      .where(
        and(
          lt(noteLayouts.reminderAt, now),
          isNull(notes.archivedAt)
        )
      );

    if (pendingReminders.length === 0) {
      logger.info('[ReminderWorker] No pending personal reminders found');
      return;
    }

    logger.info(`[ReminderWorker] Found ${pendingReminders.length} pending personal reminder(s)`);

    // Process each reminder
    for (const reminder of pendingReminders) {
      await processPersonalReminder(reminder);
    }

    logger.info('[ReminderWorker] Personal reminder check completed');
  } catch (error) {
    logger.error('[ReminderWorker] Error checking personal reminders:', error);
  }
}

/**
 * Process a single personal reminder - send notification and clear reminderAt
 */
async function processPersonalReminder(reminder: any): Promise<void> {
  try {
    logger.info(`[ReminderWorker] Processing personal reminder for note: ${reminder.noteId}, user: ${reminder.userId}`);

    // Emit reminder event (will be handled by notification system)
    const reminderEvent: PersonalNoteReminderEvent = {
      noteId: reminder.noteId,
      title: reminder.noteTitle,
      userId: reminder.userId,
      reminderAt: reminder.reminderAt,
    };

    await emitEvent('note:personal_reminder', reminderEvent);

    // Clear reminderAt to prevent duplicate notifications
    await db
      .update(noteLayouts)
      .set({
        reminderAt: null,
        updatedAt: new Date(),
      })
      .where(eq(noteLayouts.id, reminder.layoutId));

    logger.info(`[ReminderWorker] Personal reminder processed for note: ${reminder.noteId}, user: ${reminder.userId}`);
  } catch (error) {
    logger.error(`[ReminderWorker] Error processing personal reminder for note ${reminder.noteId}, user ${reminder.userId}:`, error);
  }
}
