/// <summary>
        /// Checks if there were any changes in major stats
        /// Major stats are: Level, Quickplay Wins, Competitive Wins, Competitive Rank
        /// </summary>
        /// <param Name="oldStats">OStatsResult representing the stats before the Timer elapsed</param>
        /// <param Name="newStats">OStatsResult representing the stats after the Timer elapsed</param>
        /// <returns>A Dictionary with changed stats as Key, and a string presenting them as Value</returns>
        private async Task <Dictionary <string, string> > getChangedStatsAsync(OStatsResult oldStats, OStatsResult newStats)
        {
            Dictionary <string, string> changedStats = new Dictionary <string, string>();

            OverallStats quickNew = newStats.getNotNull().stats.quickplay.overall_stats;
            OverallStats quickOld = oldStats.getNotNull().stats.quickplay.overall_stats;

            var curLevel = await OverallStats.GetLevelAsync(Name);

            if (StatGraph.PlotDataPoints.Last().Value.Value < curLevel)
            {
                changedStats.Add("Level", (curLevel) +
                                 $" (+{(curLevel) - (StatGraph.PlotDataPoints.Last().Value.Value)})");
            }

            if (quickNew.wins > quickOld.wins)
            {
                changedStats.Add("Games won", quickNew.wins.ToString() +
                                 $" (+{quickNew.wins - quickOld.wins})");
            }

            if (oldStats.getNotNull().stats.competitive != null)
            {
                OverallStats compNew = newStats.getNotNull().stats.competitive.overall_stats;
                OverallStats compOld = oldStats.getNotNull().stats.competitive.overall_stats;

                if (compNew.comprank != compOld.comprank)
                {
                    int difference = compNew.comprank - compOld.comprank;
                    changedStats.Add("Comp Rank", compNew.comprank.ToString() +
                                     $" ({(difference > 0 ? "+" : "") + difference})");
                }

                if (compNew.wins > compOld.wins)
                {
                    changedStats.Add("Comp Games won", compNew.wins.ToString() +
                                     $" (+{compNew.wins - compOld.wins})");
                }
            }

            if (quickNew.endorsement_level != quickOld.endorsement_level)
            {
                changedStats.Add("Endorsement Level", quickNew.endorsement_level.ToString());
            }

            return(changedStats);
        }
        ///<summary>Builds an embed out of the changed stats, and sends it as a Discord message </summary>
        /// <param Name="overwatchInformation">All fetched stats of the user </param>
        /// <param Name="changedStats">All changed stats of the user, together with a string presenting them </param>
        /// <param Name="mostPlayed">The most played Hero of the session, together with a string presenting them </param>
        private Embed createEmbed(OStatsResult overwatchInformation, Dictionary <string, string> changedStats, Tuple <string, string> mostPlayed)
        {
            OverallStats stats = overwatchInformation.getNotNull().stats.quickplay.overall_stats;

            EmbedBuilder e = new EmbedBuilder();

            e.Color = new Color(255, 152, 0);
            e.Title = "New Stats!";
            e.Url   = $"https://playoverwatch.com/en-us/career/pc/eu/{Name}";

            EmbedAuthorBuilder author = new EmbedAuthorBuilder();

            author.Name    = Name.Split("-")[0];
            author.Url     = $"https://playoverwatch.com/en-us/career/pc/eu/{Name}";
            author.IconUrl = stats.avatar;
            e.Author       = author;

            EmbedFooterBuilder footer = new EmbedFooterBuilder();

            footer.IconUrl = "http://i.imgur.com/YZ4w2ey.png";
            footer.Text    = "Overwatch";
            e.Timestamp    = DateTime.Now;
            e.Footer       = footer;

            foreach (var kvPair in changedStats)
            {
                e.AddField(kvPair.Key, kvPair.Value, true);
            }

            e.AddField("Sessions most played Hero", $"{mostPlayed.Item2}");
            if (mostPlayed.Item1.Equals("Ana") || mostPlayed.Item1.Equals("Moira") || mostPlayed.Item1.Equals("Orisa") || mostPlayed.Item1.Equals("Doomfist") ||
                mostPlayed.Item1.Equals("Sombra") || mostPlayed.Item1.Equals("Brigitte") || mostPlayed.Item1.Equals("Wrecking-Ball") || mostPlayed.Item1.Equals("Ashe"))
            {
                e.ThumbnailUrl = $"https://blzgdapipro-a.akamaihd.net/hero/{mostPlayed.Item1.ToLower()}/full-portrait.png";
            }
            else
            {
                e.ThumbnailUrl = $"https://blzgdapipro-a.akamaihd.net/media/thumbnail/{mostPlayed.Item1.ToLower()}-gameplay.jpg";
            }

            e.ImageUrl = StatGraph.DrawPlot();

            return(e.Build());
        }
        /// <summary>
        /// Event for the Timer, to check for changed stats
        /// </summary>
        /// <param Name="stateinfo"></param>
        public async override void CheckForChange_Elapsed(object stateinfo)
        {
            try
            {
                OStatsResult newInformation;

                lock (APILock)
                {
                    newInformation = FetchJSONDataAsync <OStatsResult>($"https://owapi.net/api/v3/u/{Name}/blob").Result;
                    Task.Delay(2500).Wait();
                }

                //OWAPI or PlayOverwatch messed up
                if (newInformation.getNotNull() == null)
                {
                    return;
                }

                if (StatGraph == null)
                {
                    StatGraph = new DatePlot(Name, "Date", "Level", "dd-MMM", false);
                    StatGraph.AddValue("Level", await OverallStats.GetLevelAsync(Name));
                    await UpdateTracker();
                }

                if (information == null)
                {
                    information = newInformation;
                }

                if (newInformation == null)
                {
                    return;
                }

                var changedStats = await getChangedStatsAsync(information, newInformation);

                if (changedStats.Count != 0)
                {
                    StatGraph.AddValue("Level", StatGraph.PlotDataPoints.Last().Value.Value);
                    StatGraph.AddValue("Level", await OverallStats.GetLevelAsync(Name));

                    foreach (ulong channel in ChannelConfig.Keys.ToList())
                    {
                        await OnMajorChangeTracked(channel, createEmbed(newInformation, changedStats, getSessionMostPlayed(information.getNotNull().heroes.playtime, newInformation.getNotNull().heroes.playtime)), (string)ChannelConfig[channel]["Notification"]);
                    }

                    information = newInformation;
                    await UpdateTracker();
                }
            }
            catch (Exception e)
            {
                await Program.MopsLog(new LogMessage(LogSeverity.Error, "", $" error by {Name}", e));

                if (e.Message.Contains("TOO MANY REQUESTS"))
                {
                    //var nextElapse = StaticBase.ran.Next(10000, 300000);
                    //checkForChange.Change(nextElapse, 300000);
                    await Program.MopsLog(new LogMessage(LogSeverity.Info, "", $"Trying again next cycle", e));
                }
            }
        }