
using System.Text;
using dodohold.core;
using System.Net;


namespace molilian.core
{
    public partial class JdUnionPlus
    {
        static Random _random = new Random();
        private WebProxy? _proxy = null;

        public TkConfigDTO _config;
        private static JdPoolDTO _account;
        private static string _end_point;

        static JdUnionPlus()
        {
            _end_point = Environment.GetEnvironmentVariable("EndPoint");
        }

        public JdUnionPlus(JdPoolDTO account)
        {
            _account = account;
            _config = TkConfigCore.Get();

            if (!string.IsNullOrEmpty(account.nodeName))
            {
                _proxy = ProxyNodesCore.GetOne(account.nodeName);
            }
        }


        private string _sign(string method, string version, string param_json, string timestamp)
        {
            Dictionary<string, string> sysParameters = new()
            {
                { "360buy_param_json", param_json },
                { "access_token", ""},
                { "app_key", _account.app_key },
                { "method", method},
                { "timestamp", timestamp },
                { "v", version }
            };

            StringBuilder stringBuilder = new();
            foreach ((var key, var value) in sysParameters)
            {
                stringBuilder.Append(key);
                stringBuilder.Append(value);
            }
            string strParameters = _account.app_secret + stringBuilder.ToString() + _account.app_secret;
            string result = strParameters.MD5(false, false);
            return result;
        }


        public string Request(string method, string version, string param_json)
        {
            var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var sign = _sign(method, version, param_json, timestamp);
            timestamp = timestamp.UrlEncode().Replace(" ", "+");

            string api = "https://api.jd.com/routerjson";
            string url = api;
            url += "?access_token=";
            url += $"&app_key={_account.app_key}";
            url += $"&method={method.UrlEncode()}";
            url += $"&v={version.UrlEncode()}";
            url += $"&sign={sign}";
            url += $"&360buy_param_json={param_json.UrlEncode()}";
            url += $"&timestamp={timestamp}";


            var log = new LoggerLibrary("jdunion", method).Info(url);
            var client = new WebClientUtility();
            var response = client.Request(url);
            var body = response.Body();
            _ = log.Info(body).SaveAsync();

            //var root = body.Convert2JsonElement();
            return body;
        }
        public async Task<string> RequestAsync(string method, string version, string param_json, CancellationToken cancellationToken = default)
        {
            var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            var sign = _sign(method, version, param_json, timestamp);
            timestamp = timestamp.UrlEncode().Replace(" ", "+");

            string api = "https://api.jd.com/routerjson";
            string url = api;
            url += "?access_token=";
            url += $"&app_key={_account.app_key}";
            url += $"&method={method.UrlEncode()}";
            url += $"&v={version.UrlEncode()}";
            url += $"&sign={sign}";
            url += $"&360buy_param_json={param_json.UrlEncode()}";
            url += $"&timestamp={timestamp}";


            var log = new LoggerLibrary("jdunion", method).Info(url);
            var client = new WebClientUtility();
            var response = await client.RequestAsync(url, "GET", cancellationToken);
            var body = response.Body();
            _ = log.Info(body).SaveAsync();

            return body;
        }

        public static bool ShouldIgnoreRequest(TkConfigDTO config, string ip, string oaid, out string reason)
        {
            reason = string.Empty;
            try
            {
                // IP和流量控制
                string ignorePercentageCity = config.jdIgnorePercentageCity;
                string? ipInfo = IP2RegionPlus.Search(ip);
                if (AlimamaPlus.IgnoreRegionIncluded(ignorePercentageCity, ipInfo, out string regionInfo))
                {
                    reason = $"地区控制：{regionInfo}";
                    return true;
                }

                int limit_num = config.jd_limit_per_ip_24h;
                if (limit_num > 0)
                {
                    int num = TkLogCore.getClientRequestTotalByIp(TkChannelEnum.jd, ip);
                    if (num > limit_num)
                    {
                        reason = "IP控制";
                        return true;
                    }
                    num = TkLogCore.getClientRequestTotalByOAID(TkChannelEnum.jd, oaid);
                    if (num > limit_num)
                    {
                        reason = "OAID控制";
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                reason = "配置异常";
            }
            return false;
        }

        public static bool FlowControlIgnoreRequest(TkConfigDTO config, out string reason)
        {
            reason = string.Empty;
            try
            {
                // IP和流量控制
                int ignorePercentage = config.jdIgnorePercentage;
                if (ignorePercentage == 0) return false;


                var randomValue = (decimal)_random.Next(0, 100);
                bool result = randomValue <= ignorePercentage; // 如果生成的随机数小于忽略百分比，则返回 true，表示需要忽略请求
                if (result)
                {
                    reason = "流量控制";
                    return true;
                }
            }
            catch (Exception ex)
            {
                reason = $"配置异常";
            }
            return false;
        }
    }
}
