using System;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using System.Threading;
using System.Threading.Tasks;
namespace Svrnty.CQRS.Events.Abstractions.Context;
///
/// Context for emitting strongly-typed events from command handlers.
/// The framework manages correlation ID assignment and event emission.
///
/// The base type or marker interface for events this command can emit.
public interface IEventContext
where TEvents : ICorrelatedEvent
{
///
/// Load or create a correlation ID based on business data.
/// Use this for multi-step workflows where correlation should be determined by business logic
/// rather than explicitly passing correlation IDs between commands.
///
/// Example: eventContext.LoadAsync((inviterUserId: 123, invitedEmail: "user@example.com"))
///
/// The framework will:
/// - Hash the key to create a stable identifier
/// - Look up existing correlation ID for this key
/// - If found, use it for all emitted events
/// - If not found, create new correlation ID and store the mapping
///
/// The type representing the correlation key (can be tuple, record, or any serializable type).
/// Business data that uniquely identifies this workflow (e.g., user IDs, email addresses).
/// Cancellation token.
Task LoadAsync(TCorrelationKey correlationKey, CancellationToken cancellationToken = default);
///
/// Emit an event. The framework will automatically assign correlation IDs and persist the event.
/// If LoadAsync was called, uses the loaded correlation ID. Otherwise, generates a new one.
///
/// The event to emit. Must be of type TEvents or derived from it.
void Emit(TEvents @event);
}