import fs from "node:fs/promises";
import path from "node:path";
import { getDb, isDatabaseConfigured } from "../db";
import { ENV } from "./env";

type RuntimeHealthState = "starting" | "ready" | "maintenance" | "shutting_down";

const startedAt = Date.now();
let ready = false;
let shuttingDown = false;

function resolveMaintenanceFlagPath() {
  return path.resolve(ENV.maintenanceFlagPath || path.join(process.cwd(), "uploads/system/maintenance.flag"));
}

async function fileExists(filePath: string) {
  try {
    await fs.access(filePath);
    return true;
  } catch {
    return false;
  }
}

export function markRuntimeReady() {
  ready = true;
}

export function markRuntimeShuttingDown() {
  shuttingDown = true;
  ready = false;
}

export async function isMaintenanceModeEnabled() {
  return fileExists(resolveMaintenanceFlagPath());
}

export async function buildRuntimeHealth() {
  const uptimeMs = Date.now() - startedAt;
  const db = await getDb();
  const databaseOk = !isDatabaseConfigured() || Boolean(db);
  const startupDelaySatisfied = uptimeMs >= ENV.appReadyDelayMs;
  const maintenance = await isMaintenanceModeEnabled();

  let state: RuntimeHealthState = "starting";
  if (shuttingDown) {
    state = "shutting_down";
  } else if (maintenance) {
    state = "maintenance";
  } else if (ready && startupDelaySatisfied && databaseOk) {
    state = "ready";
  }

  const ok = state === "ready" || state === "maintenance";

  return {
    ok,
    state,
    service: "portail-associations",
    environment: process.env.NODE_ENV || "development",
    timestamp: new Date().toISOString(),
    uptimeMs,
    maintenance,
    checks: {
      startupDelaySatisfied,
      databaseConfigured: isDatabaseConfigured(),
      databaseOk,
      ready,
      shuttingDown,
    },
  };
}

export async function ensureMaintenanceFlagDirectory() {
  const filePath = resolveMaintenanceFlagPath();
  await fs.mkdir(path.dirname(filePath), { recursive: true });
  return filePath;
}
