using CloudGaming.Code.DataAccess;
using CloudGaming.DtoModel.Other;

using HuanMeng.DotNetCore.QuartzExtend;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudGaming.Code.Monitor;

/// <summary>
/// 订单数据统计
/// </summary>
[QuartzTrigger("OrderMonitorProcessor", "* 25 4 * * ?")]
public class OrderMonitorProcessor : AppJobBase
{
    public OrderMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory)
    {
    }

    public override async Task AppConfigProcessLoop(AppConfig appConfig, AppMonitorInfo appMonitorInfo, IServiceProvider serviceProvider, CloudGamingBase cloudGamingBase)
    {
        var dao = cloudGamingBase.Dao;
        var now = DateTime.Now.AddDays(-1);
        int day = int.Parse(now.ToString("yyyyMMdd"));
        var nowDay = DateOnly.FromDateTime(now);
        //意向订单次数
        var intendedOrder = await dao.DaoUser.Context.T_User_IntentOrder.Where(it => it.CreatedDay == day).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());

        //支付订单次数
        var paidOrders = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());

        //支付金额
        var paidOrdersPrice = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Sum(it => it.TotalPrice));
        //数据源
        var orderStatistics = await dao.DaoExt.Context.T_Statistics_Order
            .Where(it => it.LoginDay == day)
            .ToDictionaryAsync(it => it.Channel ?? "");

        var list = dao.DaoExt.Context.T_App_Channel.ToList();
        foreach (var item in list)
        {
            var key = item.ChannelId;
            if (string.IsNullOrEmpty(key))
            {
                key = "27001";
            }
            UpdateStatistics(key, intendedOrder.GetValueOrDefault(key, 0), paidOrders.GetValueOrDefault(key, 0), paidOrdersPrice.GetValueOrDefault(key, 0));

        }
        await dao.DaoExt.Context.SaveChangesAsync();
        // 更新或创建统计记录
        void UpdateStatistics(string channel, int intendedOrderCount, int paidOrders, decimal rechargeAmount)
        {
            if (!orderStatistics.TryGetValue(channel, out var statisticsUser))
            {
                statisticsUser = new T_Statistics_Order()
                {
                    RechargeAmount = 0,
                    Channel = channel,
                    CreatedAt = DateTime.Now,
                    IntendedOrderCount = 0,
                    PaidOrders = 0,
                    LoginDate = nowDay,
                    LoginDay = day,
                    UpdatedAt = DateTime.Now,
                };
                dao.DaoExt.Context.T_Statistics_Order.Add(statisticsUser);
                orderStatistics.Add(channel, statisticsUser);
            }
            statisticsUser.RechargeAmount = rechargeAmount;
            statisticsUser.IntendedOrderCount = intendedOrderCount;
            statisticsUser.PaidOrders = paidOrders;
            statisticsUser.UpdatedAt = DateTime.Now;
        }

    }
}

[QuartzTrigger("OrderHourMonitorProcessor", "0 2 * * * ?")]
public class OrderHourMonitorProcessor : AppJobBase
{
    public OrderHourMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory)
    {
    }

    public override async Task AppConfigProcessLoop(AppConfig appConfig, AppMonitorInfo appMonitorInfo, IServiceProvider serviceProvider, CloudGamingBase cloudGamingBase)
    {
        var dao = cloudGamingBase.Dao;
        var now = DateTime.Now.AddHours(-1);
        int day = int.Parse(now.ToString("yyyyMMdd"));
        var newDayHour = now.Date.AddHours(now.Hour);
        var oldDayHour = now.Date.AddHours(now.AddHours(1).Hour);
        int dayHour = int.Parse(now.ToString("yyyyMMddHH"));
        var nowDay = DateOnly.FromDateTime(now);
        //意向订单次数
        var intendedOrder = await dao.DaoUser.Context.T_User_IntentOrder.Where(it => it.CreatedDay == day && it.CreatedAt >= newDayHour && it.CreatedAt < oldDayHour).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());

        //支付订单次数
        var paidOrders = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay && it.CreatedAt >= newDayHour && it.CreatedAt < oldDayHour).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());

        //支付金额
        var paidOrdersPrice = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay && it.CreatedAt >= newDayHour && it.CreatedAt < oldDayHour).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Sum(it => it.TotalPrice));
        //数据源
        var orderStatistics = await dao.DaoExt.Context.T_Statistics_OrderHour
            .Where(it => it.LoginHour == dayHour)
            .ToDictionaryAsync(it => it.Channel ?? "");
        var list = dao.DaoExt.Context.T_App_Channel.ToList();
        foreach (var item in list)
        {
            var key = item.ChannelId;
            if (string.IsNullOrEmpty(key))
            {
                key = "27001";
            }
            UpdateStatistics(key, intendedOrder.GetValueOrDefault(key, 0), paidOrders.GetValueOrDefault(key, 0), paidOrdersPrice.GetValueOrDefault(key, 0));
        }


        await dao.DaoExt.Context.SaveChangesAsync();


        void UpdateStatistics(string channel, int intendedOrderCount, int paidOrders, decimal rechargeAmount)
        {
            if (!orderStatistics.TryGetValue(channel, out var statisticsUser))
            {
                statisticsUser = new T_Statistics_OrderHour()
                {
                    RechargeAmount = 0,
                    Channel = channel,
                    CreatedAt = DateTime.Now,
                    IntendedOrderCount = 0,
                    PaidOrders = 0,
                    LoginDate = nowDay,
                    LoginDay = day,
                    UpdatedAt = DateTime.Now,
                    LoginHour = dayHour,

                };
                dao.DaoExt.Context.T_Statistics_OrderHour.Add(statisticsUser);
                orderStatistics.Add(channel, statisticsUser);
            }
            statisticsUser.RechargeAmount = rechargeAmount;
            statisticsUser.IntendedOrderCount = intendedOrderCount;
            statisticsUser.PaidOrders = paidOrders;
            statisticsUser.UpdatedAt = DateTime.Now;
        }

    }
}
