import type { AuditEntry } from "@repo/core-shared/audit";

export type DsrFormat = "json" | "json-ld";

export type DeletionMode = "soft" | "cascade-hard";

export type DeletionReason =
  | "art-17-request"
  | "admin-expunge"
  | "retention-policy";

export type DeletionAction = "deleted" | "redacted" | "pseudonymized";

/** Row reference from a collection where the subject appears as a non-owner link. */
export type SubjectReference = {
  rowId: string;
  /** Field name in the collection that links to the subject. */
  linkedField: string;
  /** Slug of the collection containing the reference. */
  linkedThrough: string;
};

/** Per-collection data bucket within a UserDataBundle. */
export type CollectionDataBucket = {
  /** Rows directly owned by the subject (kind: "self" | "owner"). */
  asSelf?: Array<Record<string, unknown>>;
  /** Rows referencing the subject without owning the row (kind: "reference"). */
  asReference?: SubjectReference[];
};

/**
 * GDPR Art. 15/20 export payload.
 *
 * `data` is keyed by Payload collection slug. asSelf contains exportable-PII-
 * filtered rows the subject owns; asReference lists row IDs + link coordinates
 * for rows that merely reference the subject.
 */
export type UserDataBundle = {
  subjectId: string;
  /** ISO 8601 timestamp of when the export was produced. */
  exportedAt: string;
  format: DsrFormat;
  data: Record<string, CollectionDataBucket>;
  /** Audit entries scoped to this subject's activity. */
  auditLog?: AuditEntry[];
  /** JSON-LD @context URI or inline object; populated when format === "json-ld". */
  "@context"?: string | Record<string, unknown>;
};

/** Per-collection summary of what the deletion touched. */
export type DeletionAffected = {
  collection: string;
  rowsAffected: number;
  action: DeletionAction;
  /** PII field names that were NULLed when action === "redacted". */
  fields?: string[];
};

/**
 * Immutable proof of a completed GDPR Art. 17 deletion / erasure request.
 *
 * The `auditEntryId` links back to the audit log entry created at deletion
 * time, forming a tamper-evident chain for regulatory inspection.
 */
export type DeletionCertificate = {
  /** Subject ID, or "erased-{hash}" if the ID itself was purged. */
  subjectId: string;
  mode: DeletionMode;
  /** ISO 8601 timestamp of the deletion. */
  timestamp: string;
  reason: DeletionReason;
  affected: DeletionAffected[];
  /** ID of the audit log entry that recorded this operation. */
  auditEntryId: string;
};
