<?php

declare( strict_types=1 );

namespace Brightfern\Transmission;

/**
 * The provider-agnostic Access Point contract — Brightfern's core moat. The merchant
 * brings their OWN certified Access Point; we never become the network and never
 * take a per-document margin. Adding a provider (or a national clearance system
 * like Poland's KSeF) is just a new class implementing this interface.
 *
 * This contract is the RECEIVE side, which every build ships:
 *   - handleIncoming() — turn a provider webhook payload into an InboundInvoice.
 *   - poll()           — pull inbound documents when webhooks aren't used.
 *
 * Receiving is free because it is the headline differentiator (mandatory for all
 * French businesses from Sep 2026). Outbound transmission is a paid capability
 * and lives outside this contract, so it is absent from the free build entirely.
 *
 * Nothing here assumes Peppol semantics specifically: identifiers are opaque
 * strings, so a KSeF provider can implement the same methods.
 */
interface AccessPointProvider {

	/** Stable machine id, e.g. "storecove", "mock". */
	public function id(): string;

	/** Human-readable name for the settings UI. */
	public function label(): string;

	/** Whether this provider/configuration can receive inbound documents. */
	public function supportsReceiving(): bool;

	/**
	 * Convert a raw inbound webhook payload into a normalized InboundInvoice.
	 * Returns null when the payload is not an inbound-document event (e.g. a
	 * send-status callback) so the webhook controller can ignore it.
	 *
	 * @param array<string,mixed> $payload Decoded webhook body.
	 */
	public function handleIncoming( array $payload ): ?InboundInvoice;

	/**
	 * Polling fallback: fetch inbound documents not yet retrieved.
	 *
	 * @return InboundInvoice[]
	 */
	public function poll(): array;
}
