import { z } from "zod";
import { t } from "@repo/core-shared/trpc/init";
import type { IAuditLog } from "../../audit-log.interface";
import { auditProcedure } from "./procedures";

/**
 * Creates the audit admin tRPC router.
 *
 * The `auditLog` parameter is captured at router-creation time. Apps that
 * mount this router must pass the `IAuditLog` impl returned by `bindAudit`.
 *
 * @example
 * ```ts
 * const { auditLog } = bindAudit(container, { payloadConfig, sinks: ["payload", "stdout"] });
 * const appRouter = t.router({ ..., audit: createAuditRouter(auditLog) });
 * ```
 */
export function createAuditRouter(auditLog: IAuditLog) {
  return t.router({
    eraseSubject: auditProcedure
      .input(
        z
          .object({
            actorId: z.string().min(1),
            mode: z.enum(["pseudonymize", "delete"]).default("pseudonymize"),
          })
          .strict(),
      )
      .mutation(async ({ input }) => {
        await auditLog.eraseSubject(input.actorId, input.mode);
        return { ok: true as const };
      }),
  });
}

/**
 * Convenience singleton for projects that have a single audit log instance.
 * Most callers should use `createAuditRouter` and pass the IAuditLog explicitly.
 * This export is a stub that throws at call time if auditLog has not been
 * provided — it exists for type inference purposes (`AuditRouter`).
 */
export const auditRouter = createAuditRouter(
  new Proxy({} as IAuditLog, {
    get(_target, prop) {
      if (prop === "then") return undefined; // not a Promise
      throw new Error(
        `auditRouter singleton used without providing an IAuditLog. ` +
          `Use createAuditRouter(auditLog) instead.`,
      );
    },
  }),
);

export type AuditRouter = ReturnType<typeof createAuditRouter>;
