import { cookies } from "next/headers";
import { SignJWT, jwtVerify } from "jose";

export const SESSION_COOKIE_NAME = "auth_session";
export const SESSION_MAX_AGE_SECONDS = 60 * 60 * 8; // 8 hours

function getSessionSecretKey() {
	const secret = process.env.SESSION_SECRET;

	if (!secret) {
		throw new Error("SESSION_SECRET environment variable is not set");
	}

	return new TextEncoder().encode(secret);
}

function resolveCookieSecureFlag() {
	const raw = (process.env.SESSION_COOKIE_SECURE || "").trim().toLowerCase();
	if (raw === "true") return true;
	if (raw === "false") return false;

	return process.env.NODE_ENV === "production";
}

function normalizeEmailOrNull(value) {
	if (typeof value !== "string") return null;
	const s = value.trim();
	if (!s) return null;
	// Email is not case-sensitive; keep it normalized for UI consistency.
	return s.toLowerCase();
}

function normalizeMustChangePassword(value) {
	return value === true;
}

/**
 * Create a signed session JWT and store it in a HTTP-only cookie.
 */
export async function createSession({
	userId,
	role,
	branchId,
	email,
	mustChangePassword,
}) {
	if (!userId || !role) {
		throw new Error("createSession requires userId and role");
	}

	const payload = {
		userId,
		role,
		branchId: branchId ?? null,
		email: normalizeEmailOrNull(email),
		mustChangePassword: normalizeMustChangePassword(mustChangePassword),
	};

	const jwt = await new SignJWT(payload)
		.setProtectedHeader({ alg: "HS256", typ: "JWT" })
		.setIssuedAt()
		.setExpirationTime(`${SESSION_MAX_AGE_SECONDS}s`)
		.sign(getSessionSecretKey());

	const cookieStore = await cookies();

	cookieStore.set(SESSION_COOKIE_NAME, jwt, {
		httpOnly: true,
		secure: resolveCookieSecureFlag(),
		sameSite: "lax",
		path: "/",
		maxAge: SESSION_MAX_AGE_SECONDS,
	});

	return jwt;
}

/**
 * Read the current session from the HTTP-only cookie.
 */
export async function getSession() {
	const cookieStore = await cookies();
	const cookie = cookieStore.get(SESSION_COOKIE_NAME);

	if (!cookie?.value) {
		return null;
	}

	const secretKey = getSessionSecretKey();

	try {
		const { payload } = await jwtVerify(cookie.value, secretKey);

		const { userId, role, branchId, email, mustChangePassword } = payload;

		if (typeof userId !== "string" || typeof role !== "string") {
			return null;
		}

		return {
			userId,
			role,
			branchId: typeof branchId === "string" ? branchId : null,
			email: typeof email === "string" ? email : null,
			mustChangePassword: normalizeMustChangePassword(mustChangePassword),
		};
	} catch {
		const store = await cookies();
		store.set(SESSION_COOKIE_NAME, "", {
			httpOnly: true,
			secure: resolveCookieSecureFlag(),
			sameSite: "lax",
			path: "/",
			maxAge: 0,
		});

		return null;
	}
}

export async function destroySession() {
	const cookieStore = await cookies();

	cookieStore.set(SESSION_COOKIE_NAME, "", {
		httpOnly: true,
		secure: resolveCookieSecureFlag(),
		sameSite: "lax",
		path: "/",
		maxAge: 0,
	});
}
