using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Threading;
using System.Data;
using StackExchange.Redis;
using CSharpUtil;

using Newtonsoft.Json.Linq;
using System.Diagnostics;

namespace DataTransfer.tongji
{
    class UserStatistics
    {
        public static void DataDeal()
        {
            LoseUserTargetCollect();
        }

        /// <summary>
        ///  流失玩家的指标的统计
        /// </summary>
        public static void LoseUserTargetCollect()
        {
            Console.WriteLine("进入流失玩家的指标的统计方法..............");

            TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
            float curday = MathF.Floor((long)ts.TotalSeconds / 24 / 60 / 60);
            float day = curday - 1;
            //float day = MathF.Floor((long)ts.TotalSeconds / 24 / 60 / 60);
            Console.WriteLine("当前时间day==.............."+ day);
            var mem = Redis.Ins.GetDatabase(0);

            List<int> retainedlist = new List<int>();
            retainedlist.Add(1);
            retainedlist.Add(2);
            retainedlist.Add(3);
            retainedlist.Add(4);
            retainedlist.Add(5);
            retainedlist.Add(6);
            retainedlist.Add(7);
            //retainedlist.Add(14);
            //retainedlist.Add(30);

            HashEntry[] zoneidList = mem.HashGetAll(MemKey_Statistics.Zonelist());
            foreach (var item in zoneidList)
            {  
                string[] sList = item.ToString().Split(':');
                int zoneid = int.Parse(sList[0]);//区
                Console.WriteLine("zoneid............"+zoneid);

                userNumRecord(zoneid);//统计下每天的人数uid

                //下面是流失人员指标统计
                foreach (int type in retainedlist)
                {
                    Console.WriteLine("type............" + type);
                   
                    List<string> loseUIdList = loseUserListCollect(type,zoneid,day);
                    if (loseUIdList.Count <= 0)
                    {
                        continue;
                    }     
                    TargetCollect(loseUIdList,type,zoneid, day);                   
                }               
            }
        }
       
        /// <summary>
        /// 统计流失玩家uid
        /// </summary>
        /// <param name="type"></param>
        /// <param name="zoneid"></param>
        /// <param name="day"></param>
        public static List<string> loseUserListCollect(int type,int zoneid, float day)
        {
            //次日留存               
            string dayKey = MemKey_Statistics.GamerunLoginUser(zoneid, day);
            string lastDayKey = MemKey_Statistics.GamerunLoginUser(zoneid, day - type);

            List<string> loseUIdList = new List<string>();

            var mem = Redis.Ins.GetDatabase(0);
            if (!mem.KeyExists(dayKey) || !mem.KeyExists(lastDayKey))
            {
                return loseUIdList;
            }
            
            string[] list = mem.HashKeys(dayKey).ToStringArray();
            string[] nextDaylist = mem.HashKeys(lastDayKey).ToStringArray();
            
            foreach (string uid in nextDaylist)
            {
                if (!list.Contains(uid))
                {
                    Console.WriteLine("uid............" + uid);
                    loseUIdList.Add(uid);
                }
            }
            return loseUIdList;
        }

        /// <summary>
        /// 查看次日流失玩家的指标信息
        /// </summary>
        /// <param name="loseUIdList"></param>
        /// <param name="zoneid"></param>
        /// <param name="day"></param>
        public static void TargetCollect(List<string> loseUIdList,int type,int zoneid,float day)
        {
            var mem = Redis.Ins.GetDatabase(0);

            foreach (string uid in loseUIdList)
            {              
                if (!mem.KeyExists(MemKey_User.gameInfo(uid, zoneid)))
                {                  
                    continue;
                }
              
                #region----------玩家等级
                //玩家等级
                string baseInfo = mem.HashGet(MemKey_User.gameInfo(uid, zoneid), "baseInfo");
                JObject baseInfoDic = JObject.Parse(baseInfo);
                int level = int.Parse(baseInfoDic["level"].ToString());
                string k = "level-" + level;
                if (mem.HashExists(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day-type), k))
                {
                    mem.HashIncrement(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), k, 1);
                }
                else
                {
                    List<HashEntry> list = new List<HashEntry>();
                    HashEntry d = new HashEntry(k, 1);
                    list.Add(d);

                    mem.HashSet(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), list.ToArray());
                }
                #endregion

                #region--------------主线任务
                
                //主线任务
                string privateState = mem.HashGet(MemKey_User.gameInfo(uid, zoneid), "privateState");
                JObject privateStateDic = JObject.Parse(privateState); //
                JObject jtaskCardTracing = JObject.Parse(privateStateDic["taskCardTracing"].ToString());
                string taskId = "0";
                if (jtaskCardTracing.ContainsKey("1"))//主线
                {
                    taskId = jtaskCardTracing["1"].ToString();                  
                }

                string store = mem.HashGet(MemKey_User.gameInfo(uid, zoneid), "store");
                JObject storeDic = JObject.Parse(store);
                JObject taskcardsDic = JObject.Parse(storeDic["taskcards"].ToString());

                if (taskId != "0" )
                {
                    JObject dict = JObject.Parse(taskcardsDic[taskId].ToString());
                    string typeId = dict["typeId"].ToString();
                    string taskKey = "task-" + typeId;
                    if (mem.HashExists(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), taskKey))
                    {
                        mem.HashIncrement(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), taskKey, 1);
                    }
                    else
                    {
                        List<HashEntry> list = new List<HashEntry>();
                        HashEntry d = new HashEntry(taskKey, 1);
                        list.Add(d);

                        mem.HashSet(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), list.ToArray());
                    }
                }
                #endregion

                #region--------------关卡
                
                string gates = mem.HashGet(MemKey_User.gameInfo(uid, zoneid), "gates");
                JObject gatesDic = JObject.Parse(gates);
                JObject normalsDic = JObject.Parse(gatesDic["normal"].ToString());
                JObject lastgatesDic = JObject.Parse(normalsDic["gates"].ToString());
                int gateId = 0;
                foreach (KeyValuePair<string,JToken>kv in lastgatesDic)
                {
                    gateId = int.Parse(kv.Key);
                }

                string gateKey = "gateId-" + gateId;
                if (mem.HashExists(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), gateKey))
                {
                    mem.HashIncrement(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), gateKey, 1);
                }
                else
                {
                    List<HashEntry> list = new List<HashEntry>();
                    HashEntry d = new HashEntry(gateKey, 1);
                    list.Add(d);

                    mem.HashSet(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type), list.ToArray());
                }
                #endregion
            }

            DataToExcelText.excelText(MemKey_Statistics.LoseUserKeyCount(type, zoneid, day - type),type,zoneid,day - type);

        }

        /// <summary>
        /// 每天登陆人数纪录----以防刚哥记得的uid的rediskey删除
        /// </summary>
        /// <param name="zoneid"></param>
        public static void userNumRecord(int zoneid)
        {
            TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
            float day = MathF.Floor((long)ts.TotalSeconds / 24 / 60 / 60);


            var mem = Redis.Ins.GetDatabase(0);
            HashEntry[] ctxList = mem.HashGetAll(MemKey_Statistics.GamerunLoginUser(zoneid, day - 1));
            //int length = ctxList.Length;

            List<string> uidlist = new List<string>();
            foreach (var item in ctxList)
            {            
                string[] sList = item.ToString().Split(':');
                string uid = sList[0];
                uidlist.Add(uid);
            }

            List<HashEntry> list = new List<HashEntry>();
            HashEntry d = new HashEntry(day-1,uidlist.ToString());
            list.Add(d);

            mem.HashSet(MemKey_Statistics.userNumRecord(zoneid), list.ToArray());
        }
    }
}
