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("GameMonitorProcessor", "* 5 4 * * ?")]
    public class GameMonitorProcessor : AppJobBase
    {
        public GameMonitorProcessor(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 gamePlay = dao.DaoPhone.Context.T_Game_PlayGameLog.Where(it => it.CreateDay == day).AsQueryable();
            //启动游戏次数
            var gamePlayCount = await gamePlay.GroupBy(log => log.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());
            //启动游戏人数
            var gamePlayLog = await gamePlay.GroupBy(log => log.Channel).Select(group => new
            {
                Channel = group.Key,
                UserCount = group.Select(log => log.UserId).Distinct().Count()
            }).ToDictionaryAsync(it => it.Channel ?? "", it => it.UserCount);
            // 游玩时间
            var gamePlaySeconds = await gamePlay.GroupBy(log => log.Channel).Select(group => new
            {
                Channel = group.Key,
                PlayGameTotalSeconds = group.Sum(it => it.PlayGameTotalSeconds)
            }).ToDictionaryAsync(it => it.Channel ?? "", it => it.PlayGameTotalSeconds);

            // 获取当前统计数据
            var userStatistics = await dao.DaoExt.Context.T_Statistics_Game
                .Where(it => it.LoginDay == day)
                .ToDictionaryAsync(it => it.Channel ?? "");
            // 更新或创建统计记录
            void UpdateStatistics(string channel, int playGameCount, int playGameTimeCount, int startGameCount)
            {
                if (!userStatistics.TryGetValue(channel, out var statisticsUser))
                {
                    statisticsUser = new T_Statistics_Game()
                    {
                        PlayGameCount = 0,
                        Channel = channel,
                        CreatedAt = DateTime.Now,
                        PlayGameTimeCount = 0,
                        StartGameCount = 0,
                        LoginDate = nowDay,
                        LoginDay = day,
                        UpdatedAt = DateTime.Now,
                    };
                    dao.DaoExt.Context.T_Statistics_Game.Add(statisticsUser);
                    userStatistics.Add(channel, statisticsUser);
                }
                statisticsUser.PlayGameCount = playGameCount;
                statisticsUser.PlayGameTimeCount = playGameTimeCount > 0 ? playGameTimeCount / 60 / 60 : playGameTimeCount;
                statisticsUser.StartGameCount = startGameCount;
                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, gamePlayCount.GetValueOrDefault(key, 0), gamePlaySeconds.GetValueOrDefault(key, 0), gamePlayLog.GetValueOrDefault(key, 0));

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

    /// <summary>
    /// 游戏控制器
    /// </summary>
    [QuartzTrigger("GameMonitorProcessorHour", "0 10 * * * ?")]
    public class GameMonitorProcessorHour : AppJobBase
    {
        public GameMonitorProcessorHour(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 gamePlay = dao.DaoPhone.Context.T_Game_PlayGameLog.Where(it => it.CreateDay == day && it.CreateDateTime >= newDayHour && it.CreateDateTime < oldDayHour).AsQueryable();
            //启动游戏次数
            var gamePlayCount = await gamePlay.GroupBy(log => log.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());
            //启动游戏人数
            var gamePlayLog = await gamePlay.GroupBy(log => log.Channel).Select(group => new
            {
                Channel = group.Key,
                UserCount = group.Select(log => log.UserId).Distinct().Count()
            }).ToDictionaryAsync(it => it.Channel ?? "", it => it.UserCount);
            // 游玩时间
            var gamePlaySeconds = await gamePlay.GroupBy(log => log.Channel).Select(group => new
            {
                Channel = group.Key,
                PlayGameTotalSeconds = group.Sum(it => it.PlayGameTotalSeconds)
            }).ToDictionaryAsync(it => it.Channel ?? "", it => it.PlayGameTotalSeconds);

            // 获取当前统计数据
            var userStatistics = await dao.DaoExt.Context.T_Statistics_GameHour
                .Where(it => it.LoginDay == day && it.LoginHour == dayHour)
                .ToDictionaryAsync(it => it.Channel ?? "");
            // 更新或创建统计记录
            void UpdateStatistics(string channel, int playGameCount, int playGameTimeCount, int startGameCount)
            {
                if (!userStatistics.TryGetValue(channel, out var statisticsUser))
                {
                    statisticsUser = new T_Statistics_GameHour()
                    {
                        PlayGameCount = 0,
                        Channel = channel,
                        CreatedAt = DateTime.Now,
                        PlayGameTimeCount = 0,
                        StartGameCount = 0,
                        LoginDate = nowDay,
                        LoginDay = day,
                        UpdatedAt = DateTime.Now,
                        LoginHour = dayHour,
                    };
                    dao.DaoExt.Context.T_Statistics_GameHour.Add(statisticsUser);
                    userStatistics.Add(channel, statisticsUser);
                }
                statisticsUser.PlayGameCount = playGameCount;
                statisticsUser.PlayGameTimeCount = (decimal)(playGameTimeCount > 0 ? playGameTimeCount / 60.0 : playGameTimeCount);
                statisticsUser.StartGameCount = startGameCount;
                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, gamePlayCount.GetValueOrDefault(key, 0), gamePlaySeconds.GetValueOrDefault(key, 0), gamePlayLog.GetValueOrDefault(key, 0));

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