import { logger } from "../../logger/index.mjs";
import { getOrganizationById } from "../../services/organization.service.mjs";
import { getProjectById } from "../../services/project.service.mjs";
import { computeEffectivePermission, getSessionRoles, intersectPermissions } from "../permissions.mjs";
import { getUserById } from "../../services/user.service.mjs";
import { mapUserToAPI } from "../mapper/user.mjs";
import { sendEmail } from "../../services/email.service.mjs";
import { mapOrganizationToAPI } from "../mapper/organization.mjs";
import { mapProjectToAPI } from "../mapper/project.mjs";
import { sendVerificationUpdate } from "../../controllers/user.controller.mjs";
import { mapSessionToAPI } from "../mapper/session.mjs";
import { passkey } from "@better-auth/passkey";
import { sso } from "@better-auth/sso";
import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { createAuthMiddleware } from "better-auth/api";
import { customSession, lastLoginMethod, twoFactor } from "better-auth/plugins";
import { magicLink } from "better-auth/plugins/magic-link";

//#region src/utils/auth/getAuth.ts
const formatSession = (session) => {
	const roles = getSessionRoles(session);
	let permissions = computeEffectivePermission(roles);
	if (session.permissions) permissions = intersectPermissions(permissions, session.permissions);
	return {
		session: session.session,
		user: session.user,
		organization: session.organization,
		project: session.project,
		authType: "session",
		permissions,
		roles
	};
};
const getAuth = (dbClient) => {
	if (!dbClient) throw new Error("MongoDB connection not established");
	return betterAuth({
		appName: "Intlayer",
		database: mongodbAdapter(dbClient.db()),
		user: { modelName: "users" },
		databaseHooks: { user: { create: { after: async (user) => {
			if (!user?.emailVerified) return;
			await sendEmail({
				type: "welcome",
				to: user.email,
				username: user.name ?? user.email.split("@")[0],
				loginLink: `${process.env.CLIENT_URL}/auth/login`,
				locale: user.lang
			});
			logger.info("Welcome e‑mail delivered", { email: user.email });
		} } } },
		hooks: { after: createAuthMiddleware(async (ctx) => {
			const { path, context } = ctx;
			const newUser = context.newSession?.user;
			const existingUser = context.session?.user;
			const user = newUser ?? existingUser;
			if (!user) return;
			if (["/verify-email"].includes(path)) {
				sendVerificationUpdate(user);
				logger.info("SSE verification update sent", {
					email: user.email,
					userId: user.id
				});
				await sendEmail({
					type: "welcome",
					to: user.email,
					username: user.name ?? user.email.split("@")[0],
					loginLink: `${process.env.CLIENT_URL}/auth/login`,
					locale: user.lang
				});
				logger.info("Welcome e‑mail delivered", { email: user.email });
			}
		}) },
		advanced: {
			cookiePrefix: "intlayer",
			cookies: { session_token: {} }
		},
		secret: process.env.BETTER_AUTH_SECRET,
		session: {
			modelName: "sessions",
			id: "id",
			additionalFields: {
				activeOrganizationId: {
					type: "string",
					nullable: true,
					input: false
				},
				activeProjectId: {
					type: "string",
					nullable: true,
					input: false
				}
			}
		},
		plugins: [
			customSession(async ({ session }) => {
				const typedSession = session;
				let userAPI = null;
				let organizationAPI = null;
				let projectAPI = null;
				if (typedSession.userId) {
					const userData = await getUserById(typedSession.userId);
					if (userData) userAPI = mapUserToAPI(userData);
				}
				if (typedSession.activeOrganizationId) {
					const orgData = await getOrganizationById(typedSession.activeOrganizationId);
					if (orgData) organizationAPI = mapOrganizationToAPI(orgData);
				}
				if (typedSession.activeProjectId) {
					const projectData = await getProjectById(typedSession.activeProjectId);
					if (projectData) projectAPI = mapProjectToAPI(projectData);
				}
				return mapSessionToAPI(formatSession({
					session: typedSession,
					user: userAPI,
					organization: organizationAPI ?? null,
					project: projectAPI ?? null,
					authType: "session"
				}));
			}),
			lastLoginMethod({
				storeInDatabase: true,
				schema: { user: { lastLoginMethod: "lastLoginMethod" } },
				customResolveMethod: (context) => {
					if (context.path === "/magic-link/verify") return "magic-link";
					return null;
				}
			}),
			passkey(),
			twoFactor(),
			magicLink({ sendMagicLink: async ({ email, url }) => {
				logger.info("sending magic link", {
					email,
					url
				});
				await sendEmail({
					type: "magicLink",
					to: email,
					username: email.split("@")[0],
					magicLink: url
				});
			} }),
			sso()
		],
		emailAndPassword: {
			enabled: true,
			disableSignUp: false,
			requireEmailVerification: true,
			minPasswordLength: 8,
			maxPasswordLength: 128,
			autoSignIn: true,
			sendResetPassword: async ({ user, token }) => {
				logger.info("sending reset password email", { email: user.email });
				await sendEmail({
					type: "resetPassword",
					to: user.email,
					username: user.name ?? user.email.split("@")[0],
					resetLink: `${process.env.CLIENT_URL}/auth/password/reset?token=${token}`
				});
			},
			resetPasswordTokenExpiresIn: 3600
		},
		accountLinking: {
			enabled: true,
			trustedProviders: [
				"google",
				"github",
				"linkedin"
			]
		},
		emailVerification: {
			autoSignInAfterVerification: true,
			sendOnSignIn: true,
			sendVerificationEmail: async ({ user, url }) => {
				logger.info("sending verification email", { email: user.email });
				await sendEmail({
					type: "validate",
					to: user.email,
					username: user.name ?? user.email.split("@")[0],
					validationLink: url
				});
			}
		},
		crossSubDomainCookies: {
			enabled: true,
			additionalCookies: ["session_token"],
			domain: process.env.CLIENT_URL
		},
		cookiePrefix: "intlayer",
		cookies: { session_token: {
			name: "session_token",
			attributes: {
				httpOnly: true,
				secure: true
			}
		} },
		trustedOrigins: [process.env.CLIENT_URL],
		socialProviders: {
			google: {
				clientId: process.env.GOOGLE_CLIENT_ID,
				clientSecret: process.env.GOOGLE_CLIENT_SECRET
			},
			github: {
				clientId: process.env.GITHUB_CLIENT_ID,
				clientSecret: process.env.GITHUB_CLIENT_SECRET
			},
			linkedin: {
				clientId: process.env.LINKEDIN_CLIENT_ID,
				clientSecret: process.env.LINKEDIN_CLIENT_SECRET
			}
		},
		logger: { log: (level, message, ...args) => logger[level](message, ...args) }
	});
};

//#endregion
export { formatSession, getAuth };
//# sourceMappingURL=getAuth.mjs.map