using QwirkleClassLibrary.Tiles;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace QwirkleClassLibrary.Players
{
    [DataContract]
    public class Leaderboard : INotifyPropertyChanged
    {
        [DataMember]
        private ObservableCollection<Score> leaderboard = new();

        public event PropertyChangedEventHandler? PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public ReadOnlyObservableCollection<Score> Lb => new(leaderboard);
        
        /// <summary>
        /// Returns the index of the player in the leaderboard, -1 if the player is not in the leaderboard
        /// </summary>
        /// <param name="playerTag"></param>
        /// <returns>int</returns>
        public int IsPlayerIn(string playerTag)
        {
            for (int i = 0; i < leaderboard.Count; i++)
            {
                if (playerTag == leaderboard[i].PlayerName)
                {
                    return i;
                }
            }
            return -1;
        }
        
        /// <summary>
        /// Adds the score of the players in the leaderboard with the date of the day and the number of victories
        /// </summary>
        /// <param name="scoreBoard"></param>
        public void AddScoreInLead(ReadOnlyDictionary<string, int> scoreBoard)
        {
            DateTime now = DateTime.Now;
            bool first = true;
            var sb = scoreBoard.OrderByDescending(x => x.Value).ThenBy(x => x.Key);

            foreach (KeyValuePair<string, int> pair in sb)
            {

                int i = IsPlayerIn(pair.Key);

                if (i != -1)
                {
                    leaderboard[i].Date = now;

                    if (first)
                    {
                        leaderboard[i].Victories++;
                        OnPropertyChanged(nameof(leaderboard));
                    }

                    if (pair.Value > leaderboard[i].Points)
                    {
                        leaderboard[i].Points = pair.Value;
                        OnPropertyChanged(nameof(leaderboard));
                    }

                }
                else
                {
                    int v = 0;
                    if (first)
                    {
                        v = 1;
                    }
                    Score score = new Score(pair.Key, now, pair.Value, v);
                    leaderboard.Add(score);
                    OnPropertyChanged(nameof(leaderboard));
                }

                first = false;
            }

            leaderboard = new ObservableCollection<Score>(leaderboard.OrderByDescending(x => x.Points).ThenBy(x => x.Victories));
        }
    }
}
