#nullable enable
using System.Text.Json;
using Baya.Application.Contracts.Payments;
using Microsoft.Extensions.Options;

namespace Baya.Infrastructure.CrossCutting.Seams;

/// <summary>
/// Deterministic mock <see cref="IWebhookVerifier"/>. It treats the signature as valid unless the raw body
/// carries the configured invalid-signature marker (so the "unverified callback mutates nothing" path is
/// testable), and extracts a test <c>external_event_id</c> / <c>event_type</c> / <c>gateway_reference_code</c>
/// from a small JSON body — which lets tests replay a duplicate callback to prove idempotency. A real adapter
/// implements the per-provider HMAC/signature scheme (or the mandatory server-side <c>verify</c> re-check).
/// </summary>
public sealed class MockWebhookVerifier(IOptions<SeamOptions> options) : IWebhookVerifier
{
    private readonly PaymentsOptions _options = options.Value.Payments;

    public WebhookVerification Verify(string provider, IReadOnlyDictionary<string, string> headers, string rawBody)
    {
        var signatureValid = !rawBody.Contains(_options.InvalidSignatureMarker, StringComparison.Ordinal);

        string externalEventId = string.Empty;
        string eventType = string.Empty;
        string? gatewayReferenceCode = null;

        try
        {
            using var doc = JsonDocument.Parse(rawBody);
            var root = doc.RootElement;
            if (root.TryGetProperty("external_event_id", out var id))
                externalEventId = id.GetString() ?? string.Empty;
            if (root.TryGetProperty("event_type", out var type))
                eventType = type.GetString() ?? string.Empty;
            if (root.TryGetProperty("gateway_reference_code", out var reference))
                gatewayReferenceCode = reference.GetString();
        }
        catch (JsonException)
        {
            // A body we can't parse yields an empty id/type; the handler stores it and no-ops (nothing to do).
        }

        var isSuccessEvent = eventType.Contains("succeed", StringComparison.OrdinalIgnoreCase);

        return new WebhookVerification(signatureValid, externalEventId, eventType, gatewayReferenceCode, isSuccessEvent);
    }
}
