/// Represents an incoming webhook event from an external platform.
class WebhookEvent {
  /// The event type as reported by the source platform
  /// (e.g. `'woocommerce.order.created'`, `'square.payment.completed'`).
  final String eventType;

  /// The source channel that emitted the event (e.g. `'woocommerce'`, `'square'`).
  final String source;

  /// The raw payload delivered with the webhook.
  final Map<String, dynamic> payload;

  /// When the event was received by the application.
  final DateTime receivedAt;

  const WebhookEvent({
    required this.eventType,
    required this.source,
    required this.payload,
    required this.receivedAt,
  });
}

/// The outcome of processing a [WebhookEvent].
enum WebhookProcessingStatus {
  /// The event was handled successfully.
  processed,

  /// The event type is not handled by this handler — it should be forwarded
  /// to another handler or silently ignored.
  ignored,

  /// Processing failed; the event may be retried depending on the delivery
  /// guarantee of the source platform.
  failed,
}

/// Result returned by [WebhookHandler.handle].
class WebhookResult {
  final WebhookProcessingStatus status;

  /// Optional human-readable detail about the outcome.
  final String? message;

  const WebhookResult({required this.status, this.message});

  const WebhookResult.processed({this.message}) : status = WebhookProcessingStatus.processed;

  const WebhookResult.ignored({this.message}) : status = WebhookProcessingStatus.ignored;

  const WebhookResult.failed({this.message}) : status = WebhookProcessingStatus.failed;
}

/// Contract for processing incoming webhook events from external platforms.
///
/// Each channel integration registers one or more [WebhookHandler]s that
/// understand its event schema. A dispatcher routes incoming events to the
/// appropriate handler based on [canHandle].
abstract class WebhookHandler {
  /// Returns `true` if this handler is capable of processing [event].
  bool canHandle(WebhookEvent event);

  /// Processes [event] and returns the outcome.
  ///
  /// Implementations should be idempotent where possible, as webhook
  /// delivery is at-least-once in most platforms.
  Future<WebhookResult> handle(WebhookEvent event);
}
