
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("UserMonitorProcessor", "* 25 4 * * ?")]
public class UserMonitorProcessor : AppJobBase
{
    public UserMonitorProcessor(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 userLoginData = cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log
            .Where(it => it.CreateTimeDay == day).AsQueryable();
        //登录数据
        var todayLoggedInUsers = await userLoginData.GroupBy(it => it.Channel ?? "")
            .ToDictionaryAsync(g => g.Key, g => g.Count());
        //注册数据
        var todayRegisteredUsers = await userLoginData.Where(it => it.IsNew)
            .GroupBy(it => it.Channel ?? "")
            .ToDictionaryAsync(g => g.Key, g => g.Count());
        //活跃数据
        var todayActionUsers = await userLoginData.Where(it => it.LogInDay > 1)
            .GroupBy(it => it.Channel ?? "")
            .ToDictionaryAsync(g => g.Key, g => g.Count());

        // 获取当前统计数据
        var userStatistics = await dao.DaoExt.Context.T_Statistics_User
            .Where(it => it.LoginDay == day)
            .ToDictionaryAsync(it => it.Channel ?? "");

        // 更新或创建统计记录
        void UpdateStatistics(string channel, int loginCount, int registrCount, int activeCount)
        {
            if (!userStatistics.TryGetValue(channel, out var statisticsUser))
            {
                statisticsUser = new T_Statistics_User()
                {
                    ActiveCount = 0,
                    Channel = channel,
                    CreatedAt = DateTime.Now,
                    LoginCount = 0,
                    RegistrCount = 0,
                    LoginDate = nowDay,
                    LoginDay = day,
                    UpdatedAt = DateTime.Now,
                };
                dao.DaoExt.Context.T_Statistics_User.Add(statisticsUser);
                userStatistics.Add(channel, statisticsUser);
            }
            statisticsUser.LoginCount = loginCount;
            statisticsUser.RegistrCount = registrCount;
            statisticsUser.ActiveCount = activeCount;
            statisticsUser.UpdatedAt = DateTime.Now;
        }
        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, todayLoggedInUsers.GetValueOrDefault(key, 0), todayRegisteredUsers.GetValueOrDefault(key, 0), todayActionUsers.GetValueOrDefault(key, 0));

        }
        await dao.DaoExt.Context.SaveChangesAsync();
    }

}

/// <summary>
/// 用户定时类   
/// </summary>
[QuartzTrigger("UserHourMonitorProcessor", "0 5 * * * ?")]
public class UserHourMonitorProcessor : AppJobBase
{
    public UserHourMonitorProcessor(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 userLoginData = cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log
            .Where(it => it.CreateTimeDay == day && it.CreateTimeHour == dayHour).AsQueryable();
        //登录数据
        var todayLoggedInUsers = await userLoginData.GroupBy(it => it.Channel ?? "")
            .ToDictionaryAsync(g => g.Key, g => g.Count());
        //注册数据
        var todayRegisteredUsers = await userLoginData.Where(it => it.IsNew)
            .GroupBy(it => it.Channel ?? "")
            .ToDictionaryAsync(g => g.Key, g => g.Count());


        // 获取当前统计数据
        var userStatistics = await dao.DaoExt.Context.T_Statistics_UserHour
            .Where(it => it.LoginDay == day && it.LoginHour == dayHour)
            .ToDictionaryAsync(it => it.Channel ?? "");

        // 更新或创建统计记录
        void UpdateStatistics(string channel, int loginCount, int registrCount)
        {
            if (!userStatistics.TryGetValue(channel, out var statisticsUser))
            {
                statisticsUser = new T_Statistics_UserHour()
                {
                    LoginHour = dayHour,
                    Channel = channel,
                    CreatedAt = DateTime.Now,
                    LoginCount = 0,
                    RegistrCount = 0,
                    LoginDate = nowDay,
                    LoginDay = day,
                    UpdatedAt = DateTime.Now,
                };
                dao.DaoExt.Context.T_Statistics_UserHour.Add(statisticsUser);
                userStatistics.Add(channel, statisticsUser);
            }
            statisticsUser.OnlineCount = appMonitorInfo?.CurrentOnlineUsers ?? 0;
            statisticsUser.LoginCount = loginCount;
            statisticsUser.RegistrCount = registrCount;
            statisticsUser.UpdatedAt = DateTime.Now;
        }
        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, todayLoggedInUsers.GetValueOrDefault(key, 0), todayRegisteredUsers.GetValueOrDefault(key, 0));

        }
        await dao.DaoExt.Context.SaveChangesAsync();
    }

}
