import { useQuery } from "@tanstack/react-query";
import { configStatusQuery } from "@/lib/queries";
import type { ConfigStatus } from "@/lib/types";

/**
 * Configuration authority as the UI must treat it: three states, never two.
 *
 * `undefined` is not database mode. Until `/api/config/status` answers, the
 * running process may be file-managed, and a form rendered on that guess
 * invites edits the server will reject. So a page shows neither an editable
 * form nor a definition list until the query resolves, and a failed query is
 * an explicit error with a way to retry.
 */
export type Authority =
	| { state: "pending" }
	| { state: "failed"; error: unknown; retry: () => void }
	| { state: "resolved"; status: ConfigStatus };

/**
 * The running server's configuration status. Every page may call this — it is
 * the shared `["configStatus"]` key, so one subscription serves them all from
 * cache.
 */
export function useAuthority(): Authority {
	const query = useQuery(configStatusQuery());
	if (query.isPending) return { state: "pending" };
	if (query.isError) {
		return {
			state: "failed",
			error: query.error,
			retry: () => void query.refetch(),
		};
	}
	return { state: "resolved", status: query.data };
}

/**
 * True unless the server has said the database owns the configuration.
 *
 * The lock is global and it fails closed: pending, failed and `managed_file`
 * all read as locked, because only a resolved database authority proves a
 * configuration mutation can succeed. Runtime actions — pause, update now,
 * reload certificates, deleting an observed client, login and logout — do not
 * consult it; they work under every authority.
 */
export function useReadOnlyConfig(): boolean {
	const authority = useAuthority();
	return !(authority.state === "resolved" && authority.status.authority === "database");
}
