import { getDb } from '../config/database.js';
import { log } from '../config/logger.js';
import { createNotification } from '../config/notifications.js';

const CHECK_INTERVAL_MS = 60_000; // every minute

let timer = null;

/**
 * Check for upcoming calendar events that need a reminder notification fired.
 * Runs every minute. Updates `reminder_sent_at` after firing so reminders
 * are never sent twice. Also resets `reminder_sent_at` to NULL when
 * start_time or reminder_minutes is changed (handled in calendar route).
 */
async function runCheck() {
  try {
    const db = getDb();

    // Fetch all events that have a reminder configured and haven't been sent yet
    const pending = await db.all(`
      SELECT ce.id, ce.uid, ce.title, ce.start_time, ce.reminder_minutes, ce.user_id,
             ce.room_uid, ce.color
      FROM calendar_events ce
      WHERE ce.reminder_minutes IS NOT NULL
        AND ce.reminder_sent_at IS NULL
    `);

    if (pending.length === 0) return;

    const now = new Date();
    const toFire = pending.filter(ev => {
      const start = new Date(ev.start_time);
      // Don't fire reminders for events that started more than 10 minutes ago (server downtime tolerance)
      if (start < new Date(now.getTime() - 10 * 60_000)) return false;
      const reminderTime = new Date(start.getTime() - ev.reminder_minutes * 60_000);
      return reminderTime <= now;
    });

    for (const ev of toFire) {
      try {
        // Mark as sent immediately to prevent double-fire even if notification creation fails
        await db.run(
          'UPDATE calendar_events SET reminder_sent_at = ? WHERE id = ?',
          [now.toISOString(), ev.id],
        );

        const start = new Date(ev.start_time);
        const timeStr = start.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
        const dateStr = start.toLocaleDateString([], { day: 'numeric', month: 'short' });
        const body = `${dateStr} · ${timeStr}`;
        const link = '/calendar';

        // Notify the owner
        await createNotification(ev.user_id, 'calendar_reminder', ev.title, body, link);

        // Notify all accepted share users as well
        const shares = await db.all(
          'SELECT user_id FROM calendar_event_shares WHERE event_id = ?',
          [ev.id],
        );
        for (const { user_id } of shares) {
          await createNotification(user_id, 'calendar_reminder', ev.title, body, link);
        }

        log.server.info(`Calendar reminder fired for event ${ev.uid} (id=${ev.id})`);
      } catch (evErr) {
        log.server.error(`Calendar reminder failed for event ${ev.id}: ${evErr.message}`);
      }
    }
  } catch (err) {
    log.server.error(`Calendar reminder job error: ${err.message}`);
  }
}

export function startCalendarReminders() {
  if (timer) return;
  // Slight delay on startup so DB is fully ready
  setTimeout(() => {
    runCheck();
    timer = setInterval(runCheck, CHECK_INTERVAL_MS);
  }, 5_000);
  log.server.info('Calendar reminder job started');
}

export function stopCalendarReminders() {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
}
