import { permissionAuditLogs } from '@/db/schema';
import { db } from '@/lib/db';

type PermissionAuditValue = Record<string, unknown> | null;

export const PERMISSION_AUDIT_ACTION = {
  TEMPLATE_CREATE: 'TEMPLATE_CREATE',
  TEMPLATE_UPDATE: 'TEMPLATE_UPDATE',
  TEMPLATE_CLONE: 'TEMPLATE_CLONE',
  TEMPLATE_ACTIVATE: 'TEMPLATE_ACTIVATE',
  TEMPLATE_DEACTIVATE: 'TEMPLATE_DEACTIVATE',
  TEMPLATE_SOFT_DELETE: 'TEMPLATE_SOFT_DELETE',
  USER_TEMPLATE_ASSIGN: 'USER_TEMPLATE_ASSIGN',
  USER_TEMPLATE_CHANGE: 'USER_TEMPLATE_CHANGE',
  USER_OVERRIDE_ALLOW: 'USER_OVERRIDE_ALLOW',
  USER_OVERRIDE_DENY: 'USER_OVERRIDE_DENY',
  USER_OVERRIDE_UPDATE: 'USER_OVERRIDE_UPDATE',
  USER_OVERRIDE_REMOVE: 'USER_OVERRIDE_REMOVE'
} as const;

export async function logPermissionAuditEvent({
  organizationId,
  actorUserId,
  targetUserId,
  templateId,
  assignmentId,
  overrideId,
  action,
  reason,
  before,
  after
}: {
  organizationId?: string | null;
  actorUserId?: string | null;
  targetUserId?: string | null;
  templateId?: number | null;
  assignmentId?: number | null;
  overrideId?: number | null;
  action: string;
  reason?: string | null;
  before?: PermissionAuditValue;
  after?: PermissionAuditValue;
}) {
  try {
    await db.insert(permissionAuditLogs).values({
      organizationId: organizationId ?? null,
      actorUserId: actorUserId ?? null,
      targetUserId: targetUserId ?? null,
      templateId: templateId ?? null,
      assignmentId: assignmentId ?? null,
      overrideId: overrideId ?? null,
      action,
      reason: reason ?? null,
      before: before ?? null,
      after: after ?? null
    });
  } catch (error) {
    console.error('Failed to write permission audit log', error);
  }
}

export function toPermissionAuditValue<T>(value: T): PermissionAuditValue {
  if (value === undefined || value === null) {
    return null;
  }

  return JSON.parse(JSON.stringify(value)) as Record<string, unknown>;
}
