import {
  pgTable,
  serial,
  timestamp,
  integer,
  varchar,
  index,
} from "drizzle-orm/pg-core";
import { usersTable } from "./users";

// Unified permission-change audit table for admin actions across user-role
// assignments, group memberships (users/roles/apps) and app-permission grants.
//
// We chose one table over per-entity tables so the API and UI can share a
// single shape and pagination semantics. Discrimination is via:
//   - targetKind:  the entity whose history this row belongs to
//                  ('user' | 'group' | 'app')
//   - targetId:    its id (kept as a plain integer because the FK target
//                  varies; the row stays valid even if the entity is later
//                  deleted)
//   - changeKind:  what set of links was modified
//                  ('user.roles' | 'user.groups' | 'group.users' |
//                   'group.roles' | 'group.apps' | 'app.permissions')
// previous_ids / new_ids store the FULL sorted set of linked ids before and
// after the change, mirroring role_permission_audit. The GET endpoint
// derives added/removed on read so the UI can render diffs without us
// duplicating that data on disk.
export const permissionAuditTable = pgTable(
  "permission_audit",
  {
    id: serial("id").primaryKey(),
    targetKind: varchar("target_kind", { length: 16 }).notNull(),
    targetId: integer("target_id").notNull(),
    changeKind: varchar("change_kind", { length: 32 }).notNull(),
    actorUserId: integer("actor_user_id").references(() => usersTable.id, {
      onDelete: "set null",
    }),
    previousIds: integer("previous_ids").array().notNull().default([]),
    newIds: integer("new_ids").array().notNull().default([]),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
  (t) => [
    index("permission_audit_target_idx").on(
      t.targetKind,
      t.targetId,
      t.createdAt,
    ),
  ],
);

export type PermissionAudit = typeof permissionAuditTable.$inferSelect;

export const PERMISSION_AUDIT_TARGET_KINDS = ["user", "group", "app"] as const;
export type PermissionAuditTargetKind =
  (typeof PERMISSION_AUDIT_TARGET_KINDS)[number];

export const PERMISSION_AUDIT_CHANGE_KINDS = [
  "user.roles",
  "user.groups",
  "group.users",
  "group.roles",
  "group.apps",
  "app.permissions",
] as const;
export type PermissionAuditChangeKind =
  (typeof PERMISSION_AUDIT_CHANGE_KINDS)[number];
