using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Text.Json;

namespace IPRS.xiaoshi.sz.com
{
    public class IPRSSearcher
    {
        private static string SearchAppId = "K8FFB741E163BE6536";
        private static string SearchAppKey = "FNYJD7902206FFB741E163BE6536C3689D55";

        string appId = "1000046";
        string appKey = "6AE6D4DC6AF94F26862501EDEE9E27A2";
        public string? GetPatents(string strCondtion,int page,int size)
        {
            int tryCount = 0;
            begin:
            string strSearchUrl = "http://s.patentstar.com.cn/SearchAPI/PatentSearch/ResultGet";
            string stamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            string queryJson = "{\"CurrentQuery\":\"" + strCondtion + "\",\"DBType\":\"CN\",\"PageNum\":" +page.ToString() + ",\"RowCount\":" + size.ToString() + ",\"OrderBy\":\"ID\",\"OrderByType\":\"ASC\"}";

            string sign = EncryptStringToMD5( SearchAppKey + stamp);

            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("AppID", SearchAppId),
                new KeyValuePair<string, string>("Stamp", stamp),
                new KeyValuePair<string, string>("Sign", sign),
                new KeyValuePair<string, string>("QueryJson", queryJson)
            });



            using (HttpClient client = new HttpClient())
            {
                try
                {
                    var retTask = client.PostAsync(strSearchUrl, content);
                    retTask.Wait();
                    return retTask.Result.Content.ReadAsStringAsync().Result;
                }
                catch(Exception ex)
                {
                    tryCount ++;
                    if(tryCount < 3)
                    {
                        System.Threading.Thread.Sleep(1000);
                        goto begin;
                    }
                    Console.WriteLine(ex.Message);
                }
            }

            return null;
        }

        private string GetIPRSData(string url)
        {
            int iTryCount = 0;
            tryAgain:
            long currentTimeMillis = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            string sign = appId + appKey + currentTimeMillis.ToString();
            string signMd5 = EncryptStringToMD5(sign);

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.Add("_appid", appId);
                    client.DefaultRequestHeaders.Add("_timestamp", currentTimeMillis.ToString());
                    client.DefaultRequestHeaders.Add("_sign", signMd5);

                    var resTask = client.GetAsync(url);
                    resTask.Wait();

                    HttpResponseMessage response = resTask.Result;
                    response.EnsureSuccessStatusCode();
                    string responseBody = response.Content.ReadAsStringAsync().Result;
                    //Console.WriteLine(responseBody);
                    return responseBody;
                }
            }
            catch (Exception ex)
            {
                iTryCount ++;
                if(iTryCount < 3)
                {
                    goto tryAgain;
                }

                return null;
            }
        }

        public string GetPatentCNBiblio(string appNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CnBibo/{appNo}";
            return GetIPRSData(url);
        }

        public string GetPatentFullTxtInfo(string appNo)
        {
            //string url = $"https://api.patentstar.com.cn/api/Patent/CnBibo/{appNo}";
            string url = $"https://api.patentstar.com.cn/api/Patent/CnFullXml/{appNo}";

            return GetIPRSData (url) ;
        }

        public string GetPatentCnMainPic(string appNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CnMainImage/{appNo}";
            return GetIPRSData(url);
        }

        public string GetPatentCNWGImage(string appNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CnWGImage/{appNo}";
            return GetIPRSData(url);
        }

        public string GetPatentCNLegal(string appNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CnLegal/{appNo}";
            return GetIPRSData(url);
        }

        public string GetPatentCNPdf(string appNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CnPdf/{appNo}";
            return GetIPRSData(url);
        }

        public string GetPatentENPdf(string pubNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/EnPdf/{pubNo}";
            return GetIPRSData(url);
        }

        public string GetPatentENBiblio(string pubNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/EnBib/{pubNo}";
            return GetIPRSData(url);
        }

        public string GetPatentFamilys(string pubNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/FamilyByPubNo/{pubNo}";
            return GetIPRSData(url);
        }

        public string GetPatentCitedNum(string pubNo)
        {
            string url = $"https://api.patentstar.com.cn/api/Patent/CitedNumByPubNo/{pubNo}";
            return GetIPRSData(url);
        }


        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="encryptString">_appid + appkey + _timestamp</param>
        /// <returns>_sign</returns>
        private string EncryptStringToMD5(string input)
        {
            // 创建一个MD5实例
            using (MD5 md5 = MD5.Create())
            {
                // 将输入字符串转换为字节数组并计算哈希值
                byte[] inputBytes = Encoding.UTF8.GetBytes(input);
                byte[] hashBytes = md5.ComputeHash(inputBytes);

                // 将字节数组转换为十六进制字符串
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hashBytes.Length; i++)
                {
                    sb.Append(hashBytes[i].ToString("X2"));
                }
                return sb.ToString();
            }
        }

        public List<string> splitCondition(string condition,DateTime startDate,DateTime endDate)
        {
            string temCond = $"{condition}*{startDate.ToString("yyyyMMdd")}>{endDate.ToString("yyyyMMdd")}/AD";
            string? strRet = GetPatents(temCond, 1, 1);
            int TotalPatents = 0;
            using (JsonDocument document = JsonDocument.Parse(strRet))
            {
                var retCode = document.RootElement.GetProperty("Ret").GetInt32();
                TotalPatents = document.RootElement.GetProperty("Data").GetProperty("HitCount").GetInt32();
            }

            if (TotalPatents > 10000)
            {
                DateTime midDate = endDate.Subtract((endDate - startDate)/2);
                
                List<string> list = new List<string>();

                List<string> lst1 = splitCondition(condition,startDate,midDate);
                List<string> lst2 = splitCondition(condition,midDate,endDate );

                list.AddRange(lst1);
                list.AddRange(lst2);

                return list;

            }
            else
            {
                if (TotalPatents > 0)
                {
                    return new List<string>() { temCond };
                }
                else
                {
                    return new List<string>();
                }
            }
        }

    }
}
