import type { UserRole } from "@/server/auth/permissions";
import { db } from "@/server/db";
import { sessions, users } from "@/server/db/schema";
import { env } from "@/utils/env";
import { DrizzleSQLiteAdapter } from "@lucia-auth/adapter-drizzle";
import { Lucia, type RegisteredDatabaseUserAttributes, type Session } from "lucia";
import { cookies } from "next/headers";
import { cache } from "react";

const adapter = new DrizzleSQLiteAdapter(db, sessions, users);

export const lucia = new Lucia(adapter, {
	sessionCookie: {
		expires: false,
		attributes: {
			secure: env.RUNTIME_ENVIRONMENT === "prod",
		},
	},
	getUserAttributes: (attributes) => {
		return {
			id: attributes.id,
			username: attributes.username,
			displayName: attributes.displayName,
			email: attributes.email,
			role: attributes.role,
		};
	},
});

export const validateRequest = cache(
	async (): Promise<{ user: RegisteredDatabaseUserAttributes; session: Session } | { user: null; session: null }> => {
		const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
		if (!sessionId) {
			return {
				user: null,
				session: null,
			};
		}

		const result = await lucia.validateSession(sessionId);
		// next.js throws when you attempt to set cookie when rendering page
		try {
			if (result.session?.fresh) {
				const sessionCookie = lucia.createSessionCookie(result.session.id);
				cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
			}
			if (!result.session) {
				const sessionCookie = lucia.createBlankSessionCookie();
				cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
			}
		} catch {}

		return result as {
			user: RegisteredDatabaseUserAttributes;
			session: Session;
		};
	},
);

declare module "lucia" {
	interface Register {
		Lucia: typeof Lucia;
		DatabaseUserAttributes: {
			id: string;
			github_id: number;
			username: string;
			displayName: string;
			email: string;
			role: UserRole;
		};
	}
}
