using DeepDrftModels.Enums;
namespace DeepDrftPublic.Client.Services;
///
/// The emit seam for the (Phase 16 §2.1). The tracker owns the session
/// lifecycle, the engagement floor, and the bucket classification but knows nothing about transport —
/// it hands a finished classification to a sink, choosing only which arm fits the close that triggered
/// it. Two arms exist because the close paths differ in whether the page survives the call (telemetry
/// transport-resilience):
///
/// - — normal closes (organic end / track-switch / stop), where the page
/// stays alive, go over a first-party HttpClient POST to api/event/play. A first-party
/// fetch is not name-matched by tracking/fingerprinting heuristics the way a sendBeacon module is.
/// - — the page-unload edge (pagehide / visibility→hidden), where an
/// awaited fetch would be cancelled, still goes over navigator.sendBeacon.
///
/// Tests substitute a fake sink to assert floor and bucket behaviour with no transport.
///
public interface IPlayEventSink
{
///
/// Emit one recorded play over the first-party fetch transport (normal close: end / switch / stop).
/// Called at most once per session, only when the floor is crossed. Awaitable but safe to
/// fire-and-forget on a live page; never throws.
///
Task EmitPlayAsync(string trackEntryKey, PlayBucket bucket);
///
/// Emit one recorded play over sendBeacon for the page-unload edge, where an awaited fetch
/// would be cancelled as the page freezes. Synchronous and fire-and-forget; never throws.
///
void EmitPlayOnUnload(string trackEntryKey, PlayBucket bucket);
}