import { useEffect, useState } from "react";

type Status = "idle" | "ok" | "error" | "disabled";

const HEALTH_CACHE_TTL_MS = 15_000;

let cachedStatus: Status = "idle";
let cachedAt = 0;
let inflightCheck: Promise<Status> | null = null;
const listeners = new Set<(status: Status) => void>();

function publishStatus(status: Status) {
  cachedStatus = status;
  cachedAt = Date.now();
  listeners.forEach((listener) => listener(status));
}

async function requestBackendHealth(): Promise<Status> {
  const controller = new AbortController();
  try {
    const response = await fetch("/api/backend/health", { signal: controller.signal });
    const payload = (await response.json().catch(() => null)) as { status?: Status } | null;
    return payload?.status ?? "error";
  } catch {
    return "error";
  } finally {
    controller.abort();
  }
}

async function ensureBackendHealthFresh(force = false): Promise<Status> {
  const now = Date.now();
  if (!force && cachedStatus !== "idle" && now - cachedAt < HEALTH_CACHE_TTL_MS) {
    return cachedStatus;
  }
  if (!inflightCheck) {
    inflightCheck = requestBackendHealth()
      .then((status) => {
        publishStatus(status);
        return status;
      })
      .finally(() => {
        inflightCheck = null;
      });
  }
  return inflightCheck;
}

export function useBackendHealth() {
  const [status, setStatus] = useState<Status>(() => cachedStatus);

  useEffect(() => {
    let destroyed = false;
    const listener = (nextStatus: Status) => {
      if (!destroyed) {
        setStatus(nextStatus);
      }
    };
    listeners.add(listener);
    void ensureBackendHealthFresh().then((nextStatus) => {
      if (!destroyed) {
        setStatus(nextStatus);
      }
    });
    return () => {
      destroyed = true;
      listeners.delete(listener);
    };
  }, []);

  return status;
}
