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

namespace DataSharing.YiBin.Enterprise
{
    public class EnterprisePusherProviderService : IEnterprisePusherProviderService, IScopeDependency
    {
        private readonly ILogger<EnterprisePusherProviderService> _logger;
        private readonly IChannelConfigurationManager _channelConfigurationManager;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly EnterpriseClient _enterpriseClient;
        private readonly ISharingConfigurationManager _sharingConfigurationManager;
        private readonly IRepository<DsWaitSendTaskOtherPlatforms> _waitSendTaskOtherPlatformsRepository;
        private readonly IRepository<DsSendTaskDetailInfo> _dsSendTaskInfoRepository;
        private readonly IRepository<DsSendTaskOtherPlatforms> _sendTaskOtherPlatformsRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="channelConfigurationManager"></param>
        /// <param name="httpClientFactory"></param>
        /// <param name="enterpriseClient"></param>
        /// <param name="sharingConfigurationManager"></param>
        /// <param name="waitSendTaskOtherPlatformsRepository"></param>
        /// <param name="dsSendTaskInfoRepository"></param>
        /// <param name="sendTaskOtherPlatformsRepository"></param>
        public EnterprisePusherProviderService(ILogger<EnterprisePusherProviderService> logger,
            IChannelConfigurationManager channelConfigurationManager,
            IHttpClientFactory httpClientFactory,
           EnterpriseClient enterpriseClient,
            ISharingConfigurationManager sharingConfigurationManager,
            IRepository<DsWaitSendTaskOtherPlatforms> waitSendTaskOtherPlatformsRepository,
            IRepository<DsSendTaskDetailInfo> dsSendTaskInfoRepository,
            IRepository<DsSendTaskOtherPlatforms> sendTaskOtherPlatformsRepository)
        {
            _logger = logger;
            _channelConfigurationManager = channelConfigurationManager;
            _httpClientFactory = httpClientFactory;
            _enterpriseClient = enterpriseClient;
            _sharingConfigurationManager = sharingConfigurationManager;
            _waitSendTaskOtherPlatformsRepository = waitSendTaskOtherPlatformsRepository;
            _dsSendTaskInfoRepository = dsSendTaskInfoRepository;
            _sendTaskOtherPlatformsRepository = sendTaskOtherPlatformsRepository;
        }

        /// <summary>
        /// 企业服务推送数据
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task SendEnterpriseDataPusher(DsWaitSendTaskOtherPlatforms dto, CancellationToken cancellationToken)
        {
            if (dto is null)
                return;

            var request = dto.Request;

            //如果存在附件，需要将附件拉取下来加载到数据里面
            if (dto.FileJson != null && dto.FileJson.Count > 0)
            {
                var data = System.Text.Json.JsonSerializer.Deserialize<PushWorkOrder>(dto.Request);

                #region 根据附件Id拉取附件文件流
                //附件处理
                List<ReplyFiles> replyFiles = new();
                foreach (var item in dto.FileJson)
                {

                    var businessFile = _channelConfigurationManager.GetConfigurationBusinessFile();
                    byte[] fileContentBytes = null;
                    try
                    {
                        #region 读取数据
                        var baseAddressFile = businessFile.BaseUrl;
                        if (!baseAddressFile.EndsWith('/'))
                            baseAddressFile += "/";

                        string url = string.Format("{0}{1}?Source={2}&Id={3}", baseAddressFile, businessFile.DownloadUrlAddress, "hotline", item.FileId);
                        using (var client = _httpClientFactory.CreateClient())
                        using (var response = await client.GetAsync(url))
                        {
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                using var memoryStream = new MemoryStream();
                                await response.Content.CopyToAsync(memoryStream);
                                memoryStream.Seek(0, SeekOrigin.Begin);
                                fileContentBytes = memoryStream.ToArray();
                            }
                        }
                        #endregion

                        #region 组装附件参数
                        //组装附件参数
                        if (fileContentBytes != null && fileContentBytes.Length > 0)
                        {
                            ReplyFiles files = new ReplyFiles
                            {
                                Filename = item.FileName,
                                Fileformat = item.FileType,
                                FileText = Convert.ToBase64String(fileContentBytes)
                            };
                            //拉取文件流
                            replyFiles.Add(files);
                        }
                        #endregion
                    }
                    catch (Exception)
                    {

                    }
                }
                #endregion

                data.ReplyFiles = replyFiles;
                request = System.Text.Json.JsonSerializer.Serialize(data);
            }

            string baseAddress = _sharingConfigurationManager.GetYiBinConfig().Enterprise.AddressUrl;
            if (!baseAddress.EndsWith('/'))
                baseAddress += "/";

            EnterpriseResponse enterprise = new();
            string error = "";
            try
            {
                enterprise = await _enterpriseClient.RequestAsync<EnterpriseResponse>(baseAddress + dto.Path, dto.HttpMethod, request, cancellationToken);
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }

            //写入推送明细表
            DsSendTaskDetailInfo dsSendTaskInfo = new()
            {
                TaskId = dto.Id,
                Result = System.Text.Json.JsonSerializer.Serialize(enterprise),
                ResultErrorData = error,
                ProcessingServices = _channelConfigurationManager.GetConfigurationProcessingServices()
            };
            //如果推送成功修改数据状态
            if (enterprise != null)
            {
                #region 处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                //处理待推送数据，如果返回成功则直接删除数据，返回失败更新数据
                if (enterprise.code == 200 && enterprise.success)
                {
                    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.Request = request;
                    data.LastTime = DateTime.Now;
                    data.SendTimes = data.SendTimes + 1;

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