using DataSharing.Province.SendTask.SubmitCaseRecord;
using DataSharing.RawData;
using DataSharing.SendTask;
using DataSharing.Share.Dtos.Province;
using DataSharing.Share.Enums;
using MapsterMapper;
using Microsoft.Extensions.Logging;
using Quartz;
using System.Text.Json;
using XF.Domain.Repository;

namespace DataSharing.Province.SendTask
{
    /// <summary>
    /// 电话记录   
    /// </summary>
    public class TaskSubmitCaseRecordJob : IJob, IDisposable
    {
        private readonly IMapper _mapper;
        private readonly ILogger<TaskSubmitCaseRecordJob> _logger;
        private readonly IRepository<DsSendTaskSubmitCaseRecord> _sendTaskSubmitCaseRecordRepository;
        private readonly IRepository<DsWaitSendTaskSubmitCaseRecord> _waitSendTaskSubmitCaseRecordRepository;
        private readonly IChannelConfigurationManager _channelConfigurationManager;
        private readonly HuiJuClient _huiJuClient;
        private readonly IRepository<DsSendTaskDetailInfo> _sendTaskDetailInfoRepository;
        private readonly IRepository<DsTelCall> _dsTelCallRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="logger"></param>
        /// <param name="sendTaskSubmitCaseRecordRepository"></param>
        /// <param name="waitSendTaskSubmitCaseRecordRepository"></param>
        /// <param name="channelConfigurationManager"></param>
        /// <param name="huiJuClient"></param>
        /// <param name="sendTaskDetailInfoRepository"></param>
        /// <param name="dsTelCallRepository"></param>
        public TaskSubmitCaseRecordJob(IMapper mapper, ILogger<TaskSubmitCaseRecordJob> logger,
            IRepository<DsSendTaskSubmitCaseRecord> sendTaskSubmitCaseRecordRepository,
            IRepository<DsWaitSendTaskSubmitCaseRecord> waitSendTaskSubmitCaseRecordRepository,
            IChannelConfigurationManager channelConfigurationManager,
            HuiJuClient huiJuClient,
           IRepository<DsSendTaskDetailInfo> sendTaskDetailInfoRepository,
           IRepository<DsTelCall> dsTelCallRepository)
        {
            _mapper = mapper;
            _logger = logger;
            _sendTaskSubmitCaseRecordRepository = sendTaskSubmitCaseRecordRepository;
            _waitSendTaskSubmitCaseRecordRepository = waitSendTaskSubmitCaseRecordRepository;
            _channelConfigurationManager = channelConfigurationManager;
            _huiJuClient = huiJuClient;
            _sendTaskDetailInfoRepository = sendTaskDetailInfoRepository;
            _dsTelCallRepository = dsTelCallRepository;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Execute(IJobExecutionContext context)
        {
            var configProvince = _channelConfigurationManager.GetConfigurationProvince();
            //加载数据
            var tasks = await _waitSendTaskSubmitCaseRecordRepository.Queryable()
           .Where(d => d.State == EWaitSendTaskState.WaitPush && d.SendTimes <= 6)
           .OrderBy(d => d.CreationTime)
           .Take(50)
           .ToListAsync(context.CancellationToken);
            _logger.LogInformation("业务汇聚-电话记录读取数据条数--------------------------------------" + tasks.Count);
            if (tasks.Count != 0)
            {
                #region 处理请求参数
                var request = new ProvinceListRequest<Share.Dtos.Province.HuiJu.SubmitCaseRecordInfo>(configProvince.ClientId, configProvince.ClientSecret);
                List<Share.Dtos.Province.HuiJu.SubmitCaseRecordInfo> listOrder = [];
                #endregion

                List<DsWaitSendTaskSubmitCaseRecord> taskData = [];

                //处理推送数据
                foreach (var sendTask in tasks)
                {
                    //状态更改为推送中
                    sendTask.State = EWaitSendTaskState.Pushing;
                    //使用乐观锁，控制数据
                    if (await _waitSendTaskSubmitCaseRecordRepository.Updateable(sendTask).ExecuteCommandWithOptLockAsync() > 0)
                    {
                        var existsTaskCall = listOrder.FirstOrDefault(p => p.PhoneNumber == sendTask.RequestData.PhoneNumber &&
                              p.PhoneStatus == sendTask.RequestData.PhoneStatus && p.AccordUrl == sendTask.RequestData.AccordUrl);

                        if (existsTaskCall is null)
                            //组装这一条数据
                            listOrder.Add(sendTask.RequestData);
                        else
                            sendTask.State = EWaitSendTaskState.StopPush;

                        taskData.Add(sendTask);
                    }
                }

                _logger.LogInformation("业务汇聚-电话记录锁定条数--------------------------------------" + taskData.Count);

                if (listOrder != null && listOrder.Count > 0)
                {
                    request.SetData(listOrder);
                    var jsonData = request.ToString();
                    _logger.LogInformation("业务汇聚-电话记录请求参数--------------------------------------" + jsonData);
                    ProvinceResponse result = new();
                    string error = "";
                    //执行推送任务
                    try
                    {
                        result = await _huiJuClient.RequestAsync<ProvinceResponse>(configProvince.HuiJu + PtahDefaults.SubmitCaseRecord, "Post", jsonData, context.CancellationToken);
                    }
                    catch (Exception ex)
                    {
                        error = ex.Message;
                    }
                    _logger.LogInformation("业务汇聚-电话记录返回参数--------------------------------------" + System.Text.RegularExpressions.Regex.Unescape(JsonSerializer.Serialize(result)));
                    if (result != null)
                    {
                        //处理数据
                        foreach (var item in taskData)
                        {
                            //如果是下一轮推送，直接将状态修改成待推送，否则正常处理
                            if (item.State == EWaitSendTaskState.StopPush)
                            {
                                item.State = EWaitSendTaskState.WaitPush;
                                //修改待推送表
                                await _waitSendTaskSubmitCaseRecordRepository.UpdateAsync(item, context.CancellationToken);
                            }
                            else
                            {
                                //查询是否有错误
                                //有错误处理
                                //没有错误删除待推送表，更新主表
                                bool isError = false;
                                if (result == null || result.Custom == null || result.ReturnInfo == null)
                                {
                                    //请求报错，那么则所有的推送失败
                                    isError = true;
                                }
                                else
                                {
                                    if (result.Custom.ErrorObjs.Exists(p => p.CaseSerial == item.ProvinceNo && p.ErrorMsg != "本次推送内容中该条数据重复，跳过"))
                                        isError = true;
                                }

                                #region 处理待推送表数据
                                //处理待推送数据
                                if (isError)
                                {
                                    //修改
                                    item.LastTime = DateTime.Now;
                                    item.SendTimes = item.SendTimes + 1;

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

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

                                    //修改待推送表
                                    await _waitSendTaskSubmitCaseRecordRepository.UpdateAsync(item, context.CancellationToken);
                                }
                                else
                                {
                                    //删除
                                    await _waitSendTaskSubmitCaseRecordRepository.RemoveAsync(item, cancellationToken: context.CancellationToken);
                                }
                                #endregion

                                #region 处理推送主表数据
                                //查询主表
                                var sendData = await _sendTaskSubmitCaseRecordRepository.GetAsync(p => p.Id == item.Id, context.CancellationToken);
                                if (sendData != null)
                                {
                                    sendData.LastTime = DateTime.Now;
                                    sendData.SendTimes = sendData.SendTimes + 1;

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

                                    sendData.IsSuccess = isError == false ? ESendTaskState.PushSuccess : ESendTaskState.PushFail;
                                    await _sendTaskSubmitCaseRecordRepository.UpdateAsync(sendData, cancellationToken: context.CancellationToken);
                                }
                                #endregion

                                #region 新增推送明细
                                //新增明细
                                DsSendTaskDetailInfo dsSendTaskDetailInfo = new()
                                {
                                    TaskId = item.Id,
                                    IsSuccess = !isError,
                                    Result = System.Text.RegularExpressions.Regex.Unescape(JsonSerializer.Serialize(result)),
                                    ResultErrorData = error,
                                    ProcessingServices = _channelConfigurationManager.GetConfigurationProcessingServices()
                                };
                                await _sendTaskDetailInfoRepository.AddAsync(dsSendTaskDetailInfo, context.CancellationToken);
                                #endregion

                                #region 上传成功后，处理通话记录的上传时间，用于统计
                                if (!isError)
                                {
                                    //处理通话记录的上传时间，用于统计
                                    var telCall = await _dsTelCallRepository.GetAsync(p => p.TaskId == item.Id, context.CancellationToken);
                                    if (telCall != null)
                                    {
                                        if (telCall.FirstSendProvinceTime is null)
                                            telCall.FirstSendProvinceTime = DateTime.Now;

                                        telCall.LastSendProvinceTime = DateTime.Now;
                                        await _dsTelCallRepository.UpdateAsync(telCall, context.CancellationToken);
                                    }
                                }
                                #endregion
                            }
                        }
                    }
                }
            }
        }



        public void Dispose()
        {

        }
    }
}
