import type { PgTransaction } from "drizzle-orm/pg-core";
import type { ExtractTablesWithRelations } from "drizzle-orm";
import type { NodePgQueryResultHKT } from "drizzle-orm/node-postgres";
import { db } from "@/db";
import * as schema from "@/db/schema";
import { auditLog } from "@/db/schema";

/**
 * Transaktionstyp des Drizzle-pg-Clients (kein `any`). Server Actions, die in
 * einer Transaktion schreiben, übergeben ihre `tx` an `writeAudit`, damit das
 * Audit-Insert Teil derselben atomaren Operation ist.
 */
export type Tx = PgTransaction<
  NodePgQueryResultHKT,
  typeof schema,
  ExtractTablesWithRelations<typeof schema>
>;

/** Audit-fähiges Ziel-Objekt. `zielId` ist eine UUID (Schema-Spalte). */
export type AuditZielTyp =
  | "brigade"
  | "user"
  | "merkmal"
  | "vehicle"
  | "equipment"
  | "vehicle_template"
  | "equipment_category";

/**
 * EINE Signatur (Querschnittsstandard 6) für alle Schreib-Actions. Mit
 * optionalem `tx`: ohne `tx` läuft das Insert auf dem Pool-`db`.
 *
 * `details` ist serialisierbares JSON (kein PII über das Nötige hinaus). Der
 * `actorUserId` referenziert `users.id` (FK set-null), sodass die Historie auch
 * nach Benutzerlöschung erhalten bleibt.
 */
export async function writeAudit(
  actorUserId: string | null,
  aktion: string,
  zielTyp: AuditZielTyp | null,
  zielId: string | null,
  details?: Record<string, unknown>,
  tx?: Tx,
): Promise<void> {
  const exec = tx ?? db;
  await exec.insert(auditLog).values({
    actorUserId: actorUserId ?? null,
    aktion,
    zielTyp,
    zielId,
    details: details ?? null,
  });
}
