using Hotline.Caching.Interfaces;
using Hotline.Orders;
using Hotline.Realtimes;
using Hotline.Share.Dtos.Bigscreen;
using Hotline.Share.Dtos.Order;
using Hotline.Share.Enums.Order;
using MapsterMapper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Hotline.Settings;
using XF.Domain.Constants;
using XF.Domain.Repository;
using Hotline.JudicialManagement;

namespace Hotline.Application.Bigscreen
{
    public class DataScreenRefreshService : BackgroundService
    {
        private readonly IServiceScopeFactory _serviceScopeFactory;

        public DataScreenRefreshService(IServiceScopeFactory serviceScopeFactory)
        {
            _serviceScopeFactory = serviceScopeFactory;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            using var scope = _serviceScopeFactory.CreateScope();
            var realtimeService = scope.ServiceProvider.GetRequiredService<IRealtimeService>();
            var _orderRepository = scope.ServiceProvider.GetRequiredService<IOrderRepository>();
            var _mapper = scope.ServiceProvider.GetRequiredService<IMapper>();
            var systemSettingCacheManager = scope.ServiceProvider.GetRequiredService<ISystemSettingCacheManager>();
            var _orderSecondaryHandlingRepository = scope.ServiceProvider.GetRequiredService<IRepository<OrderSecondaryHandling>>();
            int times = int.Parse(systemSettingCacheManager.GetSetting(SettingConstants.BsDataStateChangedTimes)?.SettingValue[0]);
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    var today = DateTime.Now;
                    var dto = new OrderCountStatisticsDto();
                    #region 当日工单量

                    dto.ToDayCount = await _orderRepository.Queryable(false, false, false)
                        .Where(x => x.StartTime.Value.Date == DateTime.Now.Date && x.Status > EOrderStatus.WaitForAccept).CountAsync();
                    var beforToDayCount = await _orderRepository.Queryable(false, false, false)
                        .Where(x => x.StartTime.Value.Date == today.AddDays(-1).Date && x.Status > EOrderStatus.WaitForAccept)
                        //.Where(x => x.StartTime.Value.Date == DateTime.Parse("2024-03-14").AddDays(-1).Date && x.Status > EOrderStatus.WaitForAccept)
                        .CountAsync();

                    if (beforToDayCount == 0)
                    {
                        dto.ToDayQoQ = 0;
                    }
                    else
                    {
                        dto.ToDayQoQ = Math.Round(((dto.ToDayCount - beforToDayCount) / (double)beforToDayCount) * 100, 2);
                    }
                    #endregion

                    #region 当月工单量

                    dto.ToMonthCount = await _orderRepository.Queryable(false, false, false).Where(x => x.StartTime.Value.ToString("yyyy-MM") == today.ToString("yyyy-MM") && x.Status > EOrderStatus.WaitForAccept).CountAsync();

                    var beforToMonthCount = await _orderRepository.Queryable(false, false, false).Where(x => x.StartTime.Value.ToString("yyyy-MM") == today.AddMonths(-1).ToString("yyyy-MM") && x.Status > EOrderStatus.WaitForAccept).CountAsync();

                    if (beforToMonthCount == 0)
                    {
                        dto.ToMonthQoQ = 0;
                    }
                    else
                    {
                        dto.ToMonthQoQ = Math.Round(((dto.ToMonthCount - beforToMonthCount) / (double)beforToMonthCount) * 100, 2);
                    }

                    #endregion

                    #region 当年工单量

                    dto.ToYearCount = await _orderRepository.Queryable(false, false, false).Where(x => x.StartTime.Value.ToString("yyyy") == today.ToString("yyyy") && x.Status > EOrderStatus.WaitForAccept).CountAsync();

                    var beforToYearCount = await _orderRepository.Queryable(false, false, false).Where(x => x.StartTime.Value.ToString("yyyy") == today.AddYears(-1).ToString("yyyy") && x.Status > EOrderStatus.WaitForAccept).CountAsync();

                    if (beforToYearCount == 0)
                    {
                        dto.ToYearQoQ = 0;
                    }
                    else
                    {
                        dto.ToYearQoQ = Math.Round(((dto.ToYearCount - beforToYearCount) / (double)beforToYearCount) * 100, 2);
                    }
                    #endregion

                    await realtimeService.OrderCountStatisticsAsync(dto, stoppingToken);
                }
                catch { }

                try
                {
                    var list = await _orderRepository
                        .Queryable(false, false, false)
                        .Where(x => x.Status > EOrderStatus.WaitForAccept && x.StartTime.Value.Date == DateTime.Now.Date)
                        //.Where(x => x.Status > EOrderStatus.WaitForAccept && x.StartTime.Value.Date == DateTime.Parse("2024-03-14").Date)
                        .OrderByDescending(x => x.StartTime)
                        .Take(50)
                        .ToListAsync();
                    var orderlist = _mapper.Map<List<OrderDto>>(list);

                    await realtimeService.OrderHandlingDetailAsync(orderlist, stoppingToken);
                }
                catch { }

                try
                {
                    var list = await _orderSecondaryHandlingRepository.Queryable().Includes(x => x.Order)
                              .Where(x => x.CreationTime.Date == DateTime.Now.Date)
                              .OrderByDescending(x => x.CreationTime)
                              .Take(50)
                             .ToListAsync();
                    var orderlist = _mapper.Map<List<OrderSecondaryHandlingDto>>(list);

                    await realtimeService.OrderSecondaryHandlingDetailAsync(orderlist, stoppingToken);
                }
                catch { }

                try
                {
                    var list = await _orderRepository
                       .Queryable(false, false, false)
                       .Where(x => x.Source == ESource.Police110 && x.StartTime.Value.Date == DateTime.Now.Date)
                       .OrderByDescending(x => x.StartTime)
                       .Take(50)
                       .ToListAsync();
                    var orderlist = _mapper.Map<List<OrderDto>>(list);

                    await realtimeService.OrderSourePoliceDetailAsync(orderlist, stoppingToken);
                }
                catch { }


                await Task.Delay(times);
            }
        }
    }
}
