using DataSharing.RawData;
using DataSharing.SendTask;
using DataSharing.SendTask.OtherPlatforms;
using DataSharing.Share.Dtos.YiBin.ZzptPlatformsYB;
using DataSharing.Share.Enums;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Text;
using XF.Domain.Dependency;
using XF.Domain.Repository;

namespace DataSharing.YiBin.ZzptPlatformsYB
{
    public class ZzptPusherProviderService : IZzptPusherProviderService, IScopeDependency
    {
        private readonly ILogger<ZzptPusherProviderService> _logger;
        private readonly IRepository<DsUserTokenInfo> _dsUserTokenInfoRepository;
        private readonly IRepository<DsWaitSendTaskOtherPlatforms> _waitSendTaskOtherPlatformsRepository;
        private readonly IRepository<DsSendTaskDetailInfo> _dsSendTaskInfoRepository;
        private readonly IRepository<DsSendTaskOtherPlatforms> _sendTaskOtherPlatformsRepository;
        private readonly IChannelConfigurationManager _channelConfigurationManager;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="dsUserTokenInfoRepository"></param>
        /// <param name="waitSendTaskOtherPlatformsRepository"></param>
        /// <param name="dsSendTaskInfoRepository"></param>
        /// <param name="sendTaskOtherPlatformsRepository"></param>
        /// <param name="channelConfigurationManager"></param>
        public ZzptPusherProviderService(ILogger<ZzptPusherProviderService> logger,
            IRepository<DsUserTokenInfo> dsUserTokenInfoRepository,
            IRepository<DsWaitSendTaskOtherPlatforms> waitSendTaskOtherPlatformsRepository,
            IRepository<DsSendTaskDetailInfo> dsSendTaskInfoRepository,
            IRepository<DsSendTaskOtherPlatforms> sendTaskOtherPlatformsRepository,
            IChannelConfigurationManager channelConfigurationManager)
        {
            _logger = logger;
            _dsUserTokenInfoRepository = dsUserTokenInfoRepository;
            _waitSendTaskOtherPlatformsRepository = waitSendTaskOtherPlatformsRepository;
            _dsSendTaskInfoRepository = dsSendTaskInfoRepository;
            _sendTaskOtherPlatformsRepository = sendTaskOtherPlatformsRepository;
            _channelConfigurationManager = channelConfigurationManager;
        }

        /// <summary>
        /// 综治平台推送数据
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task SendDataPusher(DsWaitSendTaskOtherPlatforms dto, CancellationToken cancellationToken)
        {
            if (dto is null || string.IsNullOrEmpty(dto.Request))
                return;

            var request = dto.Request;

            var dicParam = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(request);
            if (dicParam == null || dicParam.Count == 0)
                return;

            var userInfo = await _dsUserTokenInfoRepository.GetAsync(p => p.PlatformSource == EPlatformSource.ZZPT.ToString(), cancellationToken);
            if (userInfo is null || string.IsNullOrEmpty(userInfo.AddressUrl))
                return;

            var baseAddress = userInfo.AddressUrl;
            if (!baseAddress.EndsWith('/'))
                baseAddress += "/";

            string strResultJson = PostWebServiceByJson(baseAddress + dto.Path, dto.HttpMethod, dicParam);

            //写入推送明细表
            DsSendTaskDetailInfo dsSendTaskInfo = new()
            {
                TaskId = dto.Id,
                Result = strResultJson,
                ProcessingServices = _channelConfigurationManager.GetConfigurationProcessingServices()
            };
            if (false == string.IsNullOrEmpty(strResultJson))
            {
                var respone = System.Text.Json.JsonSerializer.Deserialize<ZzptDeResponse>(strResultJson);
                if (respone != null)
                {
                    #region 处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                    //处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                    if (respone.code)
                    {
                        dsSendTaskInfo.IsSuccess = true;
                        await _waitSendTaskOtherPlatformsRepository.RemoveAsync(dto, cancellationToken: cancellationToken);
                    }
                    else
                    {
                        //看看需不需要处理一些信息
                        dto.LastTime = DateTime.Now;
                        dto.SendTimes = dto.SendTimes + 1;

                        if (dto.FirstTime is null)
                            dto.FirstTime = DateTime.Now;

                        if (dto.SendTimes >= 7)
                            dto.State = EWaitSendTaskState.PushFail;
                        else
                            dto.State = EWaitSendTaskState.WaitPush;

                        await _waitSendTaskOtherPlatformsRepository.UpdateAsync(dto, cancellationToken);
                    }
                    #endregion

                    #region 处理推送主表数据
                    //处理推送主表数据
                    var data = await _sendTaskOtherPlatformsRepository.GetAsync(p => p.Id == dto.Id, cancellationToken);
                    if (data != null)
                    {
                        data.LastTime = DateTime.Now;
                        data.SendTimes = data.SendTimes + 1;

                        if (data.FirstTime is null)
                            data.FirstTime = DateTime.Now;
                        if (respone.code)
                            data.IsSuccess = ESendTaskState.PushSuccess;
                        else
                            data.IsSuccess = ESendTaskState.PushFail;
                        await _sendTaskOtherPlatformsRepository.UpdateAsync(data, cancellationToken);
                    }
                    #endregion
                }
            }
            await _dsSendTaskInfoRepository.AddAsync(dsSendTaskInfo, cancellationToken);
        }

        /// <summary>
        /// 需要WebService支持Post调用
        /// </summary>
        private string PostWebServiceByJson(string URL, string Method, Dictionary<string, string> Pars)
        {
            try
            {
                string strPars = "";
                int nIndex = 0;
                foreach (var item in Pars)
                {
                    if (0 == nIndex)
                        strPars += "?" + item.Key + "=" + item.Value;
                    else
                        strPars += "&" + item.Key + "=" + item.Value;
                    nIndex++;
                }
                string strUrl = URL + strPars;
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                if (Method.ToUpper() == "POST")
                    request.Method = "POST";
                request.Credentials = CredentialCache.DefaultCredentials;
                request.Timeout = 10000;
                byte[] data = Encoding.UTF8.GetBytes(strPars);
                request.ContentLength = data.Length;
                Stream writer = request.GetRequestStream();
                writer.Write(data, 0, data.Length);
                writer.Close();

                StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream(), Encoding.UTF8);
                String retXml = sr.ReadToEnd();
                sr.Close();
                return retXml;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

    }
}
