using System.Security.Cryptography;
using System.Text;
using Meezi.API.Configuration;
using Meezi.Core.Enums;
using Microsoft.Extensions.Options;

namespace Meezi.API.Services.Delivery;

public interface IWebhookSignatureService
{
    bool Verify(DeliveryPlatform platform, string rawBody, string? signatureHeader);
}

public class WebhookSignatureService : IWebhookSignatureService
{
    private readonly DeliveryPlatformsOptions _options;

    public WebhookSignatureService(IOptions<DeliveryPlatformsOptions> options)
    {
        _options = options.Value;
    }

    public bool Verify(DeliveryPlatform platform, string rawBody, string? signatureHeader)
    {
        var secret = platform switch
        {
            DeliveryPlatform.Snappfood => _options.Snappfood.WebhookSecret,
            DeliveryPlatform.Tap30 => _options.Tap30.WebhookSecret,
            DeliveryPlatform.Digikala => _options.Digikala.WebhookSecret,
            _ => ""
        };

        if (string.IsNullOrWhiteSpace(secret))
            return true;

        if (string.IsNullOrWhiteSpace(signatureHeader))
            return false;

        var provided = signatureHeader.Trim();
        if (provided.StartsWith("sha256=", StringComparison.OrdinalIgnoreCase))
            provided = provided["sha256=".Length..];

        var expected = ComputeHmacSha256Hex(rawBody, secret);
        return CryptographicOperations.FixedTimeEquals(
            Encoding.UTF8.GetBytes(expected),
            Encoding.UTF8.GetBytes(provided));
    }

    public static string ComputeHmacSha256Hex(string body, string secret)
    {
        using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
        var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(body));
        return Convert.ToHexString(hash).ToLowerInvariant();
    }
}
