using System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.Options;

namespace MktZaloService.Infrastructure.Zalo;

/// <summary>
/// EN: Service for verifying Zalo webhook signatures.
/// VI: Service để xác thực chữ ký webhook Zalo.
/// </summary>
public interface IZaloWebhookVerifier
{
    /// <summary>
    /// EN: Verify webhook signature using HMAC-SHA256.
    /// VI: Xác thực chữ ký webhook bằng HMAC-SHA256.
    /// </summary>
    bool VerifySignature(string requestBody, string signature);
}

/// <summary>
/// EN: Implementation of Zalo webhook signature verification.
/// VI: Implementation xác thực chữ ký webhook Zalo.
/// </summary>
public class ZaloWebhookVerifier : IZaloWebhookVerifier
{
    private readonly string _webhookSecret;

    public ZaloWebhookVerifier(IOptions<ZaloOAOptions> options)
    {
        _webhookSecret = options.Value.WebhookSecret
            ?? throw new ArgumentNullException(nameof(options), "WebhookSecret is required");
    }

    /// <summary>
    /// EN: Verify webhook signature using HMAC-SHA256.
    /// VI: Xác thực chữ ký webhook bằng HMAC-SHA256.
    /// </summary>
    public bool VerifySignature(string requestBody, string signature)
    {
        if (string.IsNullOrEmpty(requestBody) || string.IsNullOrEmpty(signature))
        {
            return false;
        }

        var computedSignature = ComputeHmacSha256(requestBody, _webhookSecret);
        return signature.Equals(computedSignature, StringComparison.OrdinalIgnoreCase);
    }

    private static string ComputeHmacSha256(string message, string secret)
    {
        var keyBytes = Encoding.UTF8.GetBytes(secret);
        var messageBytes = Encoding.UTF8.GetBytes(message);

        using var hmac = new HMACSHA256(keyBytes);
        var hashBytes = hmac.ComputeHash(messageBytes);

        return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
    }
}
