using DataSharing.FwDataExchange;
using DataSharing.RawData;
using DataSharing.SendTask;
using DataSharing.SendTask.OtherPlatforms;
using DataSharing.Share.Dtos.CityStateDataExchange;
using DataSharing.Share.Dtos.LuZhou;
using DataSharing.Share.Enums;
using DotNetCore.CAP;
using Fw.Utility.UnifyResponse;
using IdentityModel;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Tls;
using RestSharp;
using System.Net;
using System.Security.Policy;
using System.Text;
using XF.Domain.Dependency;
using XF.Domain.Repository;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace DataSharing.LuZhou.LZCityPortal
{
    public class LZCityPortalSitePusherProviderService : ILZCityPortalSitePusherProviderService, IScopeDependency
    {
        private readonly ILogger<LZCityPortalSitePusherProviderService> _logger;
        private readonly LZCityPortalSiteClient _lzCityPortalSiteClient;
        private readonly IRepository<DsWaitSendTaskOtherPlatforms> _dsSendTaskRepository;
        private readonly ICapPublisher _capPublisher;
        private readonly IRepository<DsSendTaskDetailInfo> _dsSendTaskInfoRepository;
        private readonly IRepository<DsUserTokenInfo> _dsUserTokenInfoRepository;
        private readonly IRepository<DsSendTaskOtherPlatforms> _sendTaskOtherPlatformsRepository;
        private readonly IChannelConfigurationManager _channelConfigurationManager;
        private readonly RestClient _client;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="dataExchangeClient"></param>
        /// <param name="dsSendTaskRepository"></param>
        /// <param name="capPublisher"></param>
        /// <param name="dsSendTaskInfoRepository"></param>
        /// <param name="dsUserTokenInfoRepository"></param>
        /// <param name="sendTaskOtherPlatformsRepository"></param>
        /// <param name="channelConfigurationManager"></param>
        public LZCityPortalSitePusherProviderService(ILogger<LZCityPortalSitePusherProviderService> logger,
             LZCityPortalSiteClient lzCityPortalSiteClient,
            IRepository<DsWaitSendTaskOtherPlatforms> dsSendTaskRepository,
            ICapPublisher capPublisher,
            IRepository<DsSendTaskDetailInfo> dsSendTaskInfoRepository,
            IRepository<DsUserTokenInfo> dsUserTokenInfoRepository,
            IRepository<DsSendTaskOtherPlatforms> sendTaskOtherPlatformsRepository,
            IChannelConfigurationManager channelConfigurationManager)
        {
            _logger = logger;
            _lzCityPortalSiteClient = lzCityPortalSiteClient;
            _dsSendTaskRepository = dsSendTaskRepository;
            _capPublisher = capPublisher;
            _dsSendTaskInfoRepository = dsSendTaskInfoRepository;
            _dsUserTokenInfoRepository = dsUserTokenInfoRepository;
            _sendTaskOtherPlatformsRepository = sendTaskOtherPlatformsRepository;
            _channelConfigurationManager = channelConfigurationManager;
            _client = new RestClient();
        }

        /// <summary>
        /// 市州数据交换推送数据
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task SendDataOpinionDataPusher(DsWaitSendTaskOtherPlatforms dto, CancellationToken cancellationToken)
        {
            if (dto is null)
                return;
            string TaskType = dto.TaskType;

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

            var baseAddress = userInfo.AddressUrl;
            if (!baseAddress.EndsWith('/'))
                baseAddress += "/";
            CityPortalSiteResponseDto response = new();
            string error = "";
            try
            {
                var data = JsonConvert.SerializeObject(dto.Request);
                ApiResponse apiResponse = await ExecuteAsync(baseAddress + dto.Path, Method.Post, dto.Request, cancellationToken);
                if (apiResponse != null)
                {
                    response.code = apiResponse.Code;
                    response.message = apiResponse.Message;
                }
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }

            //写入推送明细表
            DsSendTaskDetailInfo dsSendTaskInfo = new()
            {
                TaskId = dto.Id,
                Result = System.Text.Json.JsonSerializer.Serialize(response),
                ProcessingServices = _channelConfigurationManager.GetConfigurationProcessingServices(),
                ResultErrorData = error
            };

            //如果推送成功修改数据状态
            if (response != null)
            {
                #region 处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                //处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                if (response.code == 200)
                {
                    await _dsSendTaskRepository.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 _dsSendTaskRepository.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 (response.code == 200)
                        data.IsSuccess = ESendTaskState.PushSuccess;
                    else
                        data.IsSuccess = ESendTaskState.PushFail;
                    await _sendTaskOtherPlatformsRepository.UpdateAsync(data, cancellationToken);
                }
                #endregion
            }
            await _dsSendTaskInfoRepository.AddAsync(dsSendTaskInfo, cancellationToken);
        }

        public async Task<ApiResponse> ExecuteAsync<TRequest>(string path, Method httpMethod, TRequest request,
            CancellationToken cancellationToken)
            where TRequest : class
        {
            var req = new RestRequest(path, httpMethod);
            req.AddHeader("content-type", "application/json");
            if (httpMethod is Method.Get)
            {
                req.AddObject(request);
            }
            else
            {
                req.AddJsonBody(request);
            }

            try
            {
                var response = await _client.ExecuteAsync<ApiResponse>(req, cancellationToken);
                return response.Data;
            }
            catch (Exception e)
            {
                throw new HttpRequestException($"智能质检平台错误，Error: {e.Message}");
            }
        }
    }
}
