import { sql } from "drizzle-orm";
import { withTimeout } from "es-toolkit";
import { getStorageService } from "@reactive-resume/api/features/storage";
import { db } from "@reactive-resume/db/client";

const HEALTHCHECK_TIMEOUT_MS = 1_500;

type CheckResult = {
	status: "healthy" | "unhealthy";
	latencyMs: number;
	error?: string;
	[key: string]: unknown;
};

// ponytail: es-toolkit withTimeout takes a fn, not a promise — call site passes check (not check())
async function runCheck(check: () => Promise<object>): Promise<CheckResult> {
	const startedAt = performance.now();

	try {
		const data = await withTimeout(check, HEALTHCHECK_TIMEOUT_MS);
		const latencyMs = Math.round(performance.now() - startedAt);
		const result = data as { status?: string };
		if (result.status === "unhealthy") return { ...(data as object), status: "unhealthy", latencyMs };
		return { ...(data as object), status: "healthy", latencyMs };
	} catch (error) {
		return {
			status: "unhealthy",
			error: error instanceof Error ? error.message : "Unknown error",
			latencyMs: Math.round(performance.now() - startedAt),
		};
	}
}

// ponytail: inner try/catches removed; runCheck's outer catch handles all errors
async function checkDatabase() {
	await db.execute(sql`SELECT 1`);
	return { status: "healthy" };
}

const checkStorage = () => getStorageService().healthcheck();

export async function handleHealth() {
	const [database, storage] = await Promise.all([runCheck(checkDatabase), runCheck(checkStorage)]);
	const status = [database, storage].some((check) => check.status === "unhealthy") ? "unhealthy" : "healthy";

	const checks = {
		service: "reactive-resume",
		version: process.env.npm_package_version,
		status,
		timestamp: new Date().toISOString(),
		uptime: `${process.uptime().toFixed(2)}s`,
		database,
		storage,
	};

	if (status === "unhealthy") {
		console.warn("[Healthcheck]", { route: "/api/health", database, storage });
	}

	const headers = new Headers();
	const body = JSON.stringify(checks);
	headers.set("Content-Type", "application/json; charset=UTF-8");
	headers.set("Content-Length", Buffer.byteLength(body, "utf-8").toString());

	return new Response(body, {
		headers,
		status: checks.status === "unhealthy" ? 503 : 200,
	});
}
