import type { IConsent } from "./consent.interface";
import type {
  ConsentCategory,
  ConsentGrantMeta,
  UserConsentState,
} from "./consent-types";

/**
 * Volatile in-memory IConsent. State is lost on process restart.
 *
 * Used in dev-seed and test-isolation contexts where Payload is unavailable.
 * Not a recording double — use RecordingConsent from @repo/core-testing for
 * call-assertion in unit tests.
 */
export class InMemoryConsent implements IConsent {
  private state = new Map<ConsentCategory, UserConsentState>();

  isGranted(category: ConsentCategory): boolean {
    return this.state.get(category)?.state === "granted";
  }

  async grant(
    category: ConsentCategory,
    meta?: ConsentGrantMeta,
  ): Promise<void> {
    const existing = this.state.get(category);
    this.state.set(category, {
      category,
      state: "granted",
      grantedAt: new Date(),
      withdrawnAt: existing?.withdrawnAt,
      bannerVersion: meta?.bannerVersion,
      policyVersion: meta?.policyVersion,
      method: meta?.method,
    });
  }

  async withdraw(category: ConsentCategory): Promise<void> {
    const existing = this.state.get(category);
    this.state.set(category, {
      ...existing,
      category,
      state: "denied",
      withdrawnAt: new Date(),
    });
  }

  getCategories(): UserConsentState[] {
    return Array.from(this.state.values());
  }
}
