import type { IConsent } from "./consent.interface";
import type { ConsentChecked } from "@repo/core-shared/conformance";
import { attachBrand } from "@repo/core-shared/conformance";

export type { ConsentChecked };

/**
 * Use-case wrapper applied at DI bind time. Attaches the `__consentChecked`
 * brand so the boot-time assertion can verify consent-gated use cases were
 * bound through the consent-aware path.
 *
 * The forward closure keeps the brand on a fresh function so the original
 * `fn` reference is not mutated — important when the same factory output is
 * used elsewhere unwrapped (dev-seed paths, tests).
 *
 * Composition order (innermost to outermost):
 *   withSpan → withCapture → withAudit → withAnalytics → withConsent → factory(deps)
 */
export function withConsent<Args extends unknown[], R>(
  consent: IConsent,
  fn: (...args: Args) => Promise<R>,
): ConsentChecked<(...args: Args) => Promise<R>> {
  void consent;
  const wrapped: (...args: Args) => Promise<R> = (...args) => fn(...args);
  attachBrand(wrapped, "__consentChecked");
  return wrapped as ConsentChecked<(...args: Args) => Promise<R>>;
}
