using DFS.Infrastructure.Extension.SM;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace DFS.Core.Mvc.Middlewares
{
    public class SignatureValidator
    {
        private readonly ILogger<SignatureValidator> _logger;

        public SignatureValidator( ILogger<SignatureValidator> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 验证传入请求的签名是否有效。
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> ValidateSignature(HttpRequest request,string Secret)
        {
            try
            {
                var signMethod = request.Headers["sign_method"].ToString();
                var secretId = request.Headers["secret_id"].ToString();
                var nonce = request.Headers["nonce"].ToString();
                var timestamp = request.Headers["timestamp"].ToString();
                var signature = request.Headers["signature"].ToString();//签名串
                string bodyContent = string.Empty;
                if (request.Body != null)
                {
                    // 将 Body 流读取为字符串
                    request.EnableBuffering(); // 允许多次读取 Body
                    using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
                    {
                        bodyContent = await reader.ReadToEndAsync();
                    }
                    request.Body.Position = 0; // 重置流的位置以便后续读取
                }
                if (string.IsNullOrEmpty(signMethod) || string.IsNullOrEmpty(secretId) ||
                    string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(timestamp) ||
                    string.IsNullOrEmpty(signature))
                {
                    _logger.LogError("缺少签名信息");
                    return false;
                }

                // 查询字符串
                //var queryString = HttpUtility.ParseQueryString(request.QueryString.ToString());
                //var queryParameters = queryString.AllKeys
                //    .OrderBy(k => k)
                //    .Select(k => $"{k}={queryString[k]}")
                //    .Aggregate((current, next) => current + "&" + next);

                // 待签字符串
                var stringToSign = $"sign_method={signMethod}&secret_id={secretId}&nonce={nonce}&timestamp={timestamp}&{bodyContent}";
                stringToSign = stringToSign.SM4Encrypt_ECB(Secret);
                // 根据 RFC3986 对字符串进行 URL 编码
                var encodedString = Uri.EscapeDataString(stringToSign);

                string base64 = StringToBase64(encodedString);
                return base64.Equals(signature, StringComparison.Ordinal);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "签名验证过程中发生错误。");
                return false;
            }
        }

        public static string StringToBase64(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            // 将字符串转换为字节数组
            byte[] bytes = Encoding.UTF8.GetBytes(input);

            // 将字节数组转换为 Base64 字符串
            return Convert.ToBase64String(bytes);
        }
    }
}
