using CrazyStudio.Core.Common.Eitities;
using JWT;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using TouchSocket.Core;
using XPrintServer.Api.Entities;

namespace XPrintServer.Api.Tools
{
    public class RequestKelinInfo<T>
    {
        public string Url { get; set; } = "";
        public string Method { get; set; } = "POST";
        public T Data { get; set; } = default!;
        public Action<Exception> Fail { get; set; } = (error) => { };
    }

    public class HttpKelinTool
    {
        public const string BaseUrl = "https://api-beijing.klingai.com";
        //public const string BaseUrl = "https://api.klingai.com";

        public static string GenerateToken(string accessKey, string secretKey)
        {
            // 1. 设置令牌有效期（单位：毫秒）
            var expiresAt = DateTimeOffset.UtcNow.AddSeconds(1800);  // 有效时间，当前时间+30分钟
            var notBefore = DateTimeOffset.UtcNow.AddSeconds(-5);    // 开始生效的时间，当前时间-5秒

            // 4. 创建签名凭据
            var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);


            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Issuer = accessKey,
                NotBefore = notBefore.UtcDateTime,
                Expires = expiresAt.UtcDateTime,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretKeyBytes), SecurityAlgorithms.HmacSha256)
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public static async Task<dynamic?> RequestKelin<T>(RequestKelinInfo<T> requestInfo, string accessKey, string secretKey)
        {
            var token = GenerateToken(accessKey, secretKey);
            //var headers = new Dictionary<string, string> { { "Authorization", $"Bearer {token}" } };


            //var queryString = string.Join("&", canonicalQueryString
            //    .Where(kv => kv.Value != null)
            //    .Select(kv => $"{UriEscape(kv.Key)}={UriEscape(kv.Value)}"));

            var client = new HttpClient();
            string requestPayload = JsonSerializer.Serialize(requestInfo.Data);
            var request = new HttpRequestMessage
            {
                Method = new HttpMethod(requestInfo.Method),
                RequestUri = new Uri($"{BaseUrl}{requestInfo.Url}"),
                Content = new StringContent(requestPayload,
                                          Encoding.UTF8, "application/json")
            };

            request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}");

            try
            {
                var response = await client.SendAsync(request);
                var result = await response.Content.ReadFromJsonAsync<dynamic>();
                return result;
            }
            catch (Exception ex)
            {
                requestInfo.Fail(ex);
            }
            return default;
        }
    }
}
