import { QueryCtx, MutationCtx } from "../_generated/server";
import type { Id } from "../_generated/dataModel";

type AuthCtx = QueryCtx | MutationCtx;

export async function getCurrentUser(ctx: QueryCtx) {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) return null;
  return await ctx.db
    .query("users")
    .withIndex("by_external_id", (q) => q.eq("externalId", identity.subject))
    .unique();
}

export async function getCurrentUserOrThrow(ctx: AuthCtx) {
  const user = await getCurrentUser(ctx as QueryCtx);
  if (!user) throw new Error("Unauthenticated");
  return user;
}

export async function requireAdmin(ctx: QueryCtx) {
  const user = await getCurrentUserOrThrow(ctx);
  if (user.role !== "admin" && user.role !== "super_admin") {
    throw new Error("Unauthorized: admin access required");
  }
  return user;
}

export async function requireSuperAdmin(ctx: QueryCtx) {
  const user = await getCurrentUserOrThrow(ctx);
  if (user.role !== "super_admin") {
    throw new Error("Unauthorized: super_admin access required");
  }
  return user;
}

export async function requireOwnership(
  ctx: AuthCtx,
  resourceUserId: Id<"users">,
) {
  const user = await getCurrentUserOrThrow(ctx);
  if (resourceUserId !== user._id) {
    throw new Error("Unauthorized: resource does not belong to you");
  }
  return user;
}
