import type { Context, Next } from "hono";
import { getOrCreateUser, verifyApiKey } from "../services/auth.service";
import { getOrCreateUncategorized } from "../services/category.service";
import { verifyAccessToken } from "../services/oauth.service";

export async function requireAuth(c: Context, next: Next) {
	const db = c.get("db");

	// Check API key first
	const apiKey = c.req.header("X-API-Key");
	if (apiKey) {
		const result = await verifyApiKey(db, apiKey);
		if (result) {
			c.set("userId", result.userId);
			return next();
		}
		return c.json({ error: "Invalid API key" }, 401);
	}

	// Check OAuth Bearer token
	const authHeader = c.req.header("Authorization");
	if (authHeader?.startsWith("Bearer ")) {
		const token = authHeader.slice(7);
		const result = await verifyAccessToken(db, token);
		if (result) {
			c.set("userId", result.userId);
			return next();
		}
		return c.json({ error: "Invalid or expired token" }, 401);
	}

	// Check OIDC session (browser users via Logto)
	try {
		const { getAuth } = await import("@hono/oidc-auth");
		const auth = await getAuth(c);
		if (auth?.sub) {
			const user = await getOrCreateUser(db, auth.sub);
			await getOrCreateUncategorized(db, user.id);
			c.set("userId", user.id);
			return next();
		}
	} catch (err) {
		console.error("[auth] OIDC auth failed:", err);
		// OIDC not configured or session invalid — fall through
	}

	return c.json({ error: "Authentication required" }, 401);
}
