﻿using AsmodeeDigital.Common.Plugin.Manager.Coroutine;
using AsmodeeDigital.Common.Plugin.Utils.Extensions;
using AsmodeeDigital.PlayReal.Plugin.Domain.GameState;
using AsmodeeDigital.PlayReal.Plugin.Domain.Players;
using AsmodeeDigital.PlayReal.Plugin.Manager.Persistence;
using AsmodeeDigital.PlayReal.Samples.Domain.Game;
using AsmodeeDigital.PlayReal.Samples.Domain.GameState.Events;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace AsmodeeDigital.PlayReal.Samples.Logic.Gameplay
{
    /// <summary>
    /// Replay gameplay logic
    /// </summary>
    [Serializable]
    public class ReplayGameplayLogic : GameplayLogicBase
    {
        private GameStateBase ReplayGameState;

        public ReplayGameplayLogic(Persistence persistence, List<Dice> dices) : base(null, persistence, dices)
        {
        }

        /// <summary>
        /// Initialize local gameplay logic. Called by the view
        /// </summary>
        public override void Init()
        {
            base.Init();

            ReplayGameState = Persistence.GameState;

            PlayersSeats = new List<IPlayerSeat>(ReplayGameState.PlayerSeats);

            GameState.NextPlayers = PlayersSeats.ConvertAll<int>(ps => ps.LocalId);

            CoroutineManager.StartCoroutine(StartReplay());
        }

        /// <summary>
        /// Play the game state
        /// </summary>
        /// <returns></returns>
        private IEnumerator StartReplay()
        {
            bool newTurn = true;

            foreach (IEvent eventGame in ReplayGameState.Events)
            {
                DicesRolled dicesRolled = eventGame as DicesRolled;
                TurnEnded turnEnded = eventGame as TurnEnded;
                RoundEnded roundEnded = eventGame as RoundEnded;

                GameState.Events.Add(eventGame);

                if (dicesRolled != null)
                {
                    //---> If new turn, highlight player frame on the UI
                    if (newTurn)
                    {
                        newTurn = false;

                        StartNextPlayer();
                        yield return new WaitForSeconds(1f);
                    }

                    //---> Select all dice if it's the first roll of player's turn
                    if (!IsFirtDiceRoll())
                    {
                        for (int i = 0; i < dicesRolled.DicesIndicesRolled.Count; i++)
                        {
                            ChangeDiceSelection(dicesRolled.DicesIndicesRolled[i], true);
                            yield return new WaitForSeconds(0.5f);
                        }
                    }

                    RollDicesAnimation();
                    yield return new WaitForSeconds(4f);
                }
                else if(turnEnded != null)
                {
                    newTurn = true;
                }
                else if (roundEnded != null)
                {
                    List<IPlayerSeat> winners = GetWinnerLastRound();

                    RoundEnded(winners);
                    yield return new WaitForSeconds(2f);
                }
            }

            //--- At the end of the game, deselect all dices and show the game outcome panel
            Dices.ForEach(d => ChangeDiceSelection(d.Index, false));
            SetGameOutcome(false);
            //---

            yield return null;
        }

        /// <summary>
        /// Change current player, select all dices and warn the UI of player changes
        /// </summary>
        private void StartNextPlayer()
        {
            int idNextPlayer = GameState.NextPlayers.First();

            //--- Move first player in last position
            GameState.NextPlayers.RemoveAt(0);
            GameState.NextPlayers.Add(idNextPlayer);
            //---

            CurrentPlayer = this.PlayersSeats[idNextPlayer - 1];

            Dices.ForEach(d => ChangeDiceSelection(d.Index, true));

            OtherPlayerTurn();
        }
    }
}