import { auth } from "@minmon/auth";
import { db, permission, role, rolePermission, userRole } from "@minmon/db";
import type { Context as ElysiaContext } from "elysia";
import { eq } from "drizzle-orm";

export type CreateContextOptions = {
  context: ElysiaContext;
};

async function getAuthorization(userId: string) {
  const rows = await db
    .select({
      roleId: role.id,
      roleName: role.name,
      permissionName: permission.name,
    })
    .from(userRole)
    .innerJoin(role, eq(role.id, userRole.roleId))
    .innerJoin(rolePermission, eq(rolePermission.roleId, role.id))
    .innerJoin(permission, eq(permission.id, rolePermission.permissionId))
    .where(eq(userRole.userId, userId));

  return {
    roles: Array.from(new Map(rows.map((row) => [row.roleId, { id: row.roleId, name: row.roleName }])).values()),
    permissions: Array.from(new Set(rows.map((row) => row.permissionName))),
  };
}

export async function createContext({ context }: CreateContextOptions) {
  const session = await auth.api.getSession({
    headers: context.request.headers,
  });

  const authorization = session ? await getAuthorization(session.user.id) : { roles: [], permissions: [] };

  return {
    auth: null,
    session,
    authorization,
  };
}

export type Context = Awaited<ReturnType<typeof createContext>>;
