using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Serializer;
using Hncore.Pass.PaymentCenter.Model;
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Hncore.Pass.PaymentCenter.Pay.WxPay
{
    public class WxPayClient
    {
        public static readonly string url = "https://api.mch.weixin.qq.com";
        IHttpClientFactory m_HttpClientFactory;
        public WxPayClient(IHttpClientFactory _HttpClientFactory)
        {
            m_HttpClientFactory = _HttpClientFactory;
        }

        public async Task<string> CreatePayOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
        {
            var httpClient = m_HttpClientFactory.CreateClient();
            var payData = request.ToPayData();
            payData.MchKey = mchInfo.Key;
            var body = payData.ToXml();
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            var response = await httpClient
              .PostAsync($"{url}/pay/unifiedorder", new StringContent(body));

            var resText = await response.Content.ReadAsStringAsync();
            payData.FromXml(resText);
            if (payData.IsSet("err_code_des"))
            {
                LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
                return "";
            }



            if (!payData.IsSet("prepay_id"))
            {
                return "";
            }
            var appId = payData["appid"];
            var package = $"prepay_id={payData["prepay_id"]}";
            var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);
            return resp.ToJson();
        }





        public async Task<string> JsPayCreateOrderAsync(WxJsPayCreateOrderRequest request, MchInfo mchInfo)
        {
            var httpClient = m_HttpClientFactory.CreateClient();
            var payData = request.ToPayData();
            payData.MchKey = mchInfo.Key;
            var body = payData.ToXml();
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            var response = await httpClient
              .PostAsync($"{url}/pay/unifiedorder", new StringContent(body));

            var resText = await response.Content.ReadAsStringAsync();
            payData.FromXml(resText);
            if (payData.IsSet("err_code_des"))
            {
                LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
                return "";
            }

          

            if (!payData.IsSet("prepay_id"))
            {
                return "";
            }
            var appId = payData["appid"];
            var package = $"prepay_id={payData["prepay_id"]}";
            var resp = new WxJsPayInfo(appId, payData.SignType, package, mchInfo.Key);   
            return resp.ToJson();
        }

        public async Task<string> ScanPayCreateOrderAsync(WxScanPayCreateOrderRequest request, MchInfo mchInfo)
        {
            var httpClient = m_HttpClientFactory.CreateClient();
            var payData = request.ToPayData();
            payData.MchKey = mchInfo.Key;
            var body = payData.ToXml();
            LogHelper.Info("ScanPayCreateOrderAsync body", body);
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            var response = await httpClient
              .PostAsync($"{url}/pay/unifiedorder", new StringContent(body));

            var resText = await response.Content.ReadAsStringAsync();
            payData.FromXml(resText);
            if (payData.IsSet("err_code_des"))
            {          
                LogHelper.Error("ScanPayCreateOrderAsync Error", payData["err_code_des"]);
                return "";
            }
            if (!payData.IsSet("code_url"))
            {
                return "";
            }
            var code_url = payData["code_url"];       
            return code_url;
        }

        public async Task<string> H5PayCreateOrderAsync(WxH5PayCreateOrderRequest request, MchInfo mchInfo)
        {
            var httpClient = m_HttpClientFactory.CreateClient();
            var payData = request.ToPayData();
            payData.MchKey = mchInfo.Key;
            var body = payData.ToXml();
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            var response = await httpClient
              .PostAsync($"{url}/pay/unifiedorder", new StringContent(body));

            var resText = await response.Content.ReadAsStringAsync();
            payData.FromXml(resText);
            if (payData.IsSet("err_code_des"))
            {
                LogHelper.Error("H5PayCreateOrderAsync Error", payData["err_code_des"]);
                return "";
            }
            if (!payData.IsSet("mweb_url"))
            {
                return "";
            }
            var code_url = payData["mweb_url"];
            return code_url;
        }


        public async Task<bool> OrderQuery(WxJsPayOrderQueryRequest request, MchInfo mchInfo)
        {
            var httpClient = m_HttpClientFactory.CreateClient();
            request.MchId = mchInfo.MchId;
            var payData = request.ToPayData();       
            payData.MchKey = mchInfo.Key;
            var body = payData.ToXml();
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            var response = await httpClient
              .PostAsync($"{url}/pay/orderquery", new StringContent(body));

            var resText = await response.Content.ReadAsStringAsync();
            payData.FromXml(resText);

            if (payData["return_code"].ToString() == "SUCCESS" &&
                payData["result_code"].ToString() == "SUCCESS")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
