import { TRPCError } from "@trpc/server";
import { t } from "@repo/core-shared/trpc/init";
import { defineErrorMiddleware } from "@repo/core-shared/trpc/define-error-middleware";

/**
 * The minimum user shape that the adminOnly middleware expects to find on `ctx`.
 * Apps must include this field when creating their tRPC context for requests
 * that may reach admin procedures. Unauthenticated requests leave `user`
 * undefined, which the middleware treats as non-admin.
 */
export type AdminTrpcUser = {
  roles: string[];
};

/**
 * Middleware that blocks non-admin callers.
 *
 * Reads `ctx.user?.roles` from the tRPC context. Throws FORBIDDEN if the
 * user is absent or lacks the "admin" role. Apps that mount the auditRouter
 * must set `ctx.user` with the authenticated user's roles.
 */
const adminOnly = t.middleware(({ ctx, next }) => {
  const user = (ctx as { user?: AdminTrpcUser }).user;
  if (!user?.roles.includes("admin")) {
    throw new TRPCError({
      code: "FORBIDDEN",
      message: "Admin role required",
    });
  }
  return next({ ctx: { ...ctx, user } });
});

/**
 * Base procedure for all audit admin routes.
 *
 * - `adminOnly` middleware gates every mutation/query.
 * - `defineErrorMiddleware([])` — no audit-specific domain errors need tRPC
 *   mapping; the FORBIDDEN thrown by `adminOnly` is a plain TRPCError and
 *   propagates unchanged.
 */
export const auditProcedure = t.procedure
  .use(adminOnly)
  .use(defineErrorMiddleware([]));
