import "server-only";

import { cache } from "react";
import type { Schedule } from "@/lib/schedule";
import type { SettingsInput } from "@/lib/validation/settings";
import { db } from "../db";

export type MonitoringSettings = Schedule & { slowThresholdSeconds: number; updatedAt: Date };

const SINGLETON_ID = 1;

/** Uncached read — for the scheduler, which runs outside any request. */
export async function readMonitoringSettings(): Promise<MonitoringSettings> {
  // The migration seeds the row; upsert keeps a hand-emptied table from breaking the app.
  const row = await db.monitoringSettings.upsert({ where: { id: SINGLETON_ID }, update: {}, create: { id: SINGLETON_ID } });
  return {
    frequency: row.frequency,
    checkTime: row.checkTime,
    timezone: row.timezone,
    slowThresholdSeconds: row.slowThresholdSeconds,
    updatedAt: row.updatedAt,
  };
}

/** Per-request cached read — for pages (every page needs the display timezone). */
export const getMonitoringSettings = cache(readMonitoringSettings);

export async function updateMonitoringSettings(input: SettingsInput): Promise<{ changed: boolean }> {
  const current = await readMonitoringSettings();
  const scheduleChanged =
    current.frequency !== input.frequency || current.checkTime !== input.checkTime || current.timezone !== input.timezone;
  const thresholdChanged = current.slowThresholdSeconds !== input.slowThresholdSeconds;

  // Skip no-op saves: updated_at is the "only run slots after this" anchor,
  // and re-saving identical settings must not cancel today's pending run.
  // The threshold is written with raw SQL for the same reason — changing it
  // alone must not move the schedule anchor either.
  if (scheduleChanged) {
    await db.monitoringSettings.update({ where: { id: SINGLETON_ID }, data: input });
  } else if (thresholdChanged) {
    await db.$executeRaw`UPDATE monitoring_settings SET slow_threshold_seconds = ${input.slowThresholdSeconds} WHERE id = ${SINGLETON_ID}`;
  }
  return { changed: scheduleChanged || thresholdChanged };
}
