import { config } from "./config.js";
import { listUpcomingDeadlines } from "./contractsStore.js";
import { createLogger } from "./logger.js";
import { sendDeadlineNotifications } from "./notifications.js";
import { getRuntimeSettings } from "./runtimeSettings.js";

const logger = createLogger(config.logLevel);

export class DeadlineMonitor {
  private timer: NodeJS.Timeout | null = null;
  private running = false;

  start() {
    if (this.running) {
      return;
    }
    this.running = true;
    const settings = getRuntimeSettings();
    logger.info(
      `Starting deadline monitor (interval=${settings.schedulerIntervalMinutes} min, alert window=${settings.alertDaysBefore} days)`
    );
    this.scheduleNext(1000);
  }

  stop() {
    if (!this.running) {
      return;
    }
    this.running = false;
    if (this.timer) {
      clearTimeout(this.timer);
      this.timer = null;
    }
    logger.info("Deadline monitor stopped.");
  }

  private scheduleNext(delayMs?: number) {
    if (!this.running) {
      return;
    }
    const settings = getRuntimeSettings();
    const intervalMs = Math.max(settings.schedulerIntervalMinutes, 5) * 60 * 1000;
    const wait = delayMs ?? intervalMs;

    this.timer = setTimeout(() => {
      this.runCheck()
        .catch((error) => {
          logger.error("Deadline check failed", error);
        })
        .finally(() => {
          this.scheduleNext();
        });
    }, wait);
  }

  private async runCheck() {
    const settings = getRuntimeSettings();
    const deadlines = listUpcomingDeadlines(settings.alertDaysBefore);

    if (deadlines.length === 0) {
      logger.debug("No upcoming deadlines within alert window.");
      return;
    }

    const lines = deadlines.map(
      (item) =>
        `${item.title} (#${item.id}) — cancel by ${item.terminationDeadline} (${item.daysUntilDeadline} days left)`
    );

    for (const item of deadlines) {
      logger.warn(
        "Upcoming deadline: %s (provider=%s, documentId=%s, terminate by %s, days=%s)",
        item.title,
        item.provider ?? "n/a",
        item.paperlessDocumentId ?? "n/a",
        item.terminationDeadline ?? "n/a",
        item.daysUntilDeadline ?? "n/a"
      );
    }

    await sendDeadlineNotifications("Contract termination reminder", lines, settings);
  }
}

export const deadlineMonitor = new DeadlineMonitor();
