// Local type aliases mirroring exports from `@repo/core-dsr`.
// Kept inline to avoid a build-graph cycle between core-testing (tooling)
// and core-dsr (optional core). Same pattern used by RecordingAuditLog,
// RecordingConsent, and other recording doubles.

type DeletionMode = "soft" | "cascade-hard";
type DeletionReason = "art-17-request" | "admin-expunge" | "retention-policy";
type DeletionAction = "deleted" | "redacted" | "pseudonymized";

type DeletionAffected = {
  collection: string;
  rowsAffected: number;
  action: DeletionAction;
  fields?: string[];
};

type DeletionCertificate = {
  subjectId: string;
  mode: DeletionMode;
  timestamp: string;
  reason: DeletionReason;
  affected: DeletionAffected[];
  auditEntryId: string;
};

/** Recorded call to deleteSubjectData. */
export type RecordedDeleteCall = {
  subjectId: string;
  mode: DeletionMode;
};

/**
 * Test-side recording double for IDataDelete. Records all deleteSubjectData
 * calls for assertion while returning a well-shaped DeletionCertificate.
 *
 * Use directly via constructor injection:
 *   const deleter = new RecordingDataDelete();
 *   const uc = myUseCase(deleter);
 *   await uc({ ... });
 *   expect(deleter.calls[0]?.mode).toBe("soft");
 */
export class RecordingDataDelete {
  public calls: RecordedDeleteCall[] = [];

  async deleteSubjectData(
    subjectId: string,
    mode: DeletionMode,
  ): Promise<DeletionCertificate> {
    this.calls.push({ subjectId, mode });
    return {
      subjectId,
      mode,
      timestamp: new Date().toISOString(),
      reason: "art-17-request",
      affected: [],
      auditEntryId: `recording-audit-${Date.now()}`,
    };
  }

  reset(): void {
    this.calls = [];
  }
}
