using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Models.Events;
using Models.Rules;

namespace Models.Game
{
    public class Game
    {
        private bool _isRunning;
        public Player CurrentPlayer { get; private set; }

        public Map UsedMap { get; private set; }

        private Dice Dice1 { get; }
        private Dice Dice2 { get; }

        private int Turn { get; set; }

        private Rules.Rules GameRules { get; }

        // == Events ==
        public event EventHandler<GameStartedEventArgs> GameStarted;
        public event EventHandler<GameEndedEventArgs> GameEnded;
     
        
        public Game(Player player, Map map)
        {
            _isRunning = false;
            UsedMap = map;
            CurrentPlayer = player;
            Dice1 = new Dice();
            Dice2 = new Dice(1);
            Turn = 0;
            GameRules = new Rules.Rules();
        }

        public void RollAllDice()
        {
            Dice1.Roll();
            Dice2.Roll();
        }

        public int ResultOperation(Operation o)
        {
            switch (o)
            {
                case Operation.LOWER:
                    return Dice1.IsLower(Dice2) ? Dice1.Value : Dice2.Value;

                case Operation.HIGHER:
                    return Dice1.IsLower(Dice2) ? Dice2.Value : Dice1.Value;

                case Operation.SUBTRACTION:
                    return Dice1.IsLower(Dice2) ? Dice2.Value - Dice1.Value : Dice1.Value - Dice2.Value;

                case Operation.ADDITION:
                    return Dice2.Value + Dice1.Value;

                case Operation.MULTIPLICATION:
                    return Dice2.Value * Dice1.Value;
                
                default:
                    return 0;
            }
        }

        public void PlaceResult (Cell playerChoice, int result)
        {
            if (Turn == 1 || GameRules.NearCell(playerChoice, UsedMap.Boards))
            {
                playerChoice.Value = result;
            }
        }

        public void AddToRopePath(Cell cell)
        {
            if (GameRules.IsRopePath(cell, ropePaths)) return;
            
        }
        
        public void InitializeGame()
        {
            _isRunning = true;
            GameStarted?.Invoke(this, new GameStartedEventArgs(CurrentPlayer));

            GameLoop();
        }

        private async void GameLoop()
        {
            while (_isRunning)
            {
                
                if (CheckGameEnd()) //TODO Règle pour check si fin de jeu
                {
                    _isRunning = false;
                    //TODO Code pour comptabiliser les points
                    GameEnded?.Invoke(this, new GameEndedEventArgs(//player));
                }

                await Task.Delay(1000); // 1 seconde
            }
        }
    }
}
