const cron = require('node-cron');
const { getDb, getSetting } = require('../db/database');
const { buildTrackerRow, getCycleRange } = require('../services/statusService');
const { pruneExpiredSessions } = require('../services/authService');
const { runNotifications } = require('../services/notificationService');
const { runAllCleanup } = require('../services/cleanupService');
const {
  markWorkerError,
  markWorkerStarted,
  markWorkerSuccess,
} = require('../services/statusRuntime');

const DAILY_CRON_HOUR = 6;

function nextDailyRunIso(from = new Date()) {
  const next = new Date(from);
  next.setHours(DAILY_CRON_HOUR, 0, 0, 0);
  if (next <= from) next.setDate(next.getDate() + 1);
  return next.toISOString();
}

async function runDailyTasks() {
  const db = getDb();
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth() + 1;
  const todayStr = now.toISOString().slice(0, 10);
  const { start, end } = getCycleRange(year, month);

  const bills = db.prepare('SELECT * FROM bills WHERE active = 1').all();

  for (const bill of bills) {
    const payments = db.prepare(
      'SELECT * FROM payments WHERE bill_id = ? AND paid_date BETWEEN ? AND ? AND deleted_at IS NULL'
    ).all(bill.id, start, end);

    const row = buildTrackerRow(bill, payments, year, month, todayStr);

    // Auto-mark autopay bills as assumed_paid on due date
    if (
      bill.autopay_enabled &&
      bill.autodraft_status === 'pending' &&
      todayStr >= row.due_date
    ) {
      db.prepare("UPDATE bills SET autodraft_status = 'assumed_paid', updated_at = datetime('now') WHERE id = ?")
        .run(bill.id);
    }
  }

  pruneExpiredSessions();
  await runNotifications();

  // Run scheduled cleanup tasks (expired import sessions, stale temp files, etc.)
  await runAllCleanup().catch(err => {
    console.error('[worker] Cleanup error (non-fatal):', err.message);
  });

  markWorkerSuccess(nextDailyRunIso());
  console.log(`[worker] Daily tasks ran at ${todayStr}`);
}

function start() {
  markWorkerStarted(nextDailyRunIso());

  // Run once at startup
  runDailyTasks().catch(err => {
    markWorkerError(err, nextDailyRunIso());
    console.error('[worker] Startup task error:', err);
  });

  // Run every day at 6:00 AM
  cron.schedule('0 6 * * *', () => {
    runDailyTasks().catch(err => {
      markWorkerError(err, nextDailyRunIso());
      console.error('[worker] Daily task error:', err);
    });
  });
}

module.exports = { start, runDailyTasks, nextDailyRunIso };
