/**
 * MDM Healthcheck Cron
 *
 * Läuft alle 5 Minuten. Prüft für alle mit NanoMDM verknüpften iOS-Geräte
 * den aktuellen Enrollment-/Supervision-Status und spiegelt ihn auf UserDevice.
 */
import { consola } from "consola";
import {
  getLinkedUserDevices,
  getMdmEnrollmentStatusesByUdids,
  updateUserDeviceMdmHealth,
  type MdmEnrollmentStatus,
} from "../db/mdm";

const FIVE_MINUTES = 5 * 60 * 1000;
const INITIAL_DELAY_MS = 30 * 1000;

let running = false;

export default defineNitroPlugin((nitro) => {
  if (import.meta.dev) {
    consola.info("[mdm-health-cron] Skipping cron in dev mode");
    return;
  }

  consola.info("[mdm-health-cron] Starting (5min interval)");

  const initialTimer = setTimeout(() => {
    runMdmHealthCheck().catch(() => {});
  }, INITIAL_DELAY_MS);

  const interval = setInterval(() => {
    runMdmHealthCheck().catch(() => {});
  }, FIVE_MINUTES);

  nitro.hooks.hook("close", () => {
    clearTimeout(initialTimer);
    clearInterval(interval);
  });
});

async function runMdmHealthCheck() {
  if (running) {
    consola.info("[mdm-health-cron] Previous run still in progress, skipping");
    return;
  }

  running = true;
  const start = Date.now();

  try {
    const devices = await getLinkedUserDevices();
    if (devices.length === 0) {
      consola.info("[mdm-health-cron] No linked iOS devices");
      return;
    }

    const statuses = await getMdmEnrollmentStatusesByUdids(
      devices.map((d) => d.mdmId).filter((id): id is string => id != null),
    );

    let updated = 0;
    let unchanged = 0;

    for (const device of devices) {
      const status: MdmEnrollmentStatus = statuses.get(device.mdmId ?? "") ?? {
        enrolled: false,
        supervised: false,
        lastSeenAt: null,
      };

      const changed =
        device.mdmEnrolled !== status.enrolled ||
        device.mdmSupervised !== status.supervised ||
        !sameNullableDate(device.mdmLastSeenAt, status.lastSeenAt);

      if (!changed) {
        unchanged++;
        continue;
      }

      try {
        await updateUserDeviceMdmHealth(device.id, status);
        updated++;
      } catch (err: any) {
        consola.error(
          `[mdm-health-cron] Failed to update device ${device.id}: ${err?.message ?? err}`,
        );
      }
    }

    consola.success(
      `[mdm-health-cron] Checked ${devices.length} devices in ${Date.now() - start}ms (${updated} updated, ${unchanged} unchanged)`,
    );
  } catch (err: any) {
    consola.error("[mdm-health-cron] run failed:", err?.message ?? err);
  } finally {
    running = false;
  }
}

function sameNullableDate(a: Date | null, b: Date | null): boolean {
  if (a === null && b === null) return true;
  if (a === null || b === null) return false;
  return a.getTime() === b.getTime();
}
