using System.Collections.Generic;
using UnityEngine;
using BeardedManStudios.Forge.Networking.Generated;
using BeardedManStudios.Forge.Networking.Unity;
using BeardedManStudios.Forge.Networking;


public class GameManager : NetworkGameManagerBehavior
{
    public static GameManager Instance;

    private List<int> playerScores = new List<int>();

    //Gamemode Variables
    private const int maxScore = 25;
    private float secondsLeft = 600;

    private bool _isGameOver = false;

    public bool isGameOver { get { return _isGameOver; } }

    // Use this for initialization
    void Start()
    {
        // Init Singleton
        if (Instance == null) { Instance = this; } else { Destroy(this); }

        SpawnLocalPlayer();
    }

    // Why on earth are we letting the client spawn things.
    void SpawnLocalPlayer()
    {
        if (NetworkManager.Instance != null)
        {
            GameObject[] spawns = GameObject.FindGameObjectsWithTag("Player Spawn");

            int randomSpawnID = Random.Range(0, spawns.Length);

            Transform selectedSpawnPos = spawns[randomSpawnID].transform;

            NetworkManager.Instance.InstantiateNetworkPlayer(0, selectedSpawnPos.position, selectedSpawnPos.rotation);
        }
    }

    private void Update()
    {
        if(networkObject.IsServer)
        {
            // Update the list of playerScores with currently connected players.
            if(networkObject.playerCount != NetworkManager.Instance.Networker.Players.Count)
            {
                networkObject.playerCount = NetworkManager.Instance.Networker.Players.Count;
                networkObject.SendRpc(RPC_UPDATE_PLAYER_LIST, Receivers.AllBuffered);
            }

            if(secondsLeft >0)
            { 
                //Update timer.
                secondsLeft -= Time.deltaTime;

                if (secondsLeft < 0)
                    secondsLeft = 0;

                networkObject.timeLeft = secondsLeft;
            }
           
            
            // This be here for testing!
            if(Input.GetKeyDown(KeyCode.Y))
            {
                networkObject.SendRpc(RPC_ADD_SCORE, Receivers.AllBuffered, (uint)0);
            }

            //End game if timer runs out
            if(secondsLeft == 0)
            {
                networkObject.SendRpc(RPC_END_GAME, Receivers.AllBuffered);
            }
        }
        
       
        if(!networkObject.IsServer)
        {
            // Get timer on client.
            secondsLeft = networkObject.timeLeft;
        }

        // Update timer ui text.
        UIManager.Instance.timeLeftText.text = string.Format("{0}:{1:00}", (int)(secondsLeft / 60), secondsLeft % 60);
    }

    public override void SetupGameMode(RpcArgs args)
    {
       
    }

    public override void EndGame(RpcArgs args)
    {
        Debug.Log("Games over noobs get rekt!");
    }

    public override void AddScore(RpcArgs args)
    {
        if (_isGameOver)  return;


        uint playerID = args.GetNext<uint>();

        if(playerScores.Count >= playerID)
        {
            playerScores[(int)playerID]++;
        }

        Debug.Log("Player " + playerID + " scored!");

        UpdateScoreUI(playerID);

        int leadingPlayerScore = 0;

        foreach(int playerScore in playerScores)
        {
            if(playerScore > leadingPlayerScore)
            {
                leadingPlayerScore = playerScore;
            }
        }

        if(leadingPlayerScore >= maxScore)
        {
            EndGame();
        }
    }

    private void EndGame()
    {
        if (_isGameOver) return;

        _isGameOver = true;

        networkObject.SendRpc(RPC_END_GAME, Receivers.AllBuffered);
    }

    private void UpdateScoreUI(uint playerID)
    {
        if (NetworkManager.Instance.Networker.Me.NetworkId == playerID)
        {
            UIManager.Instance.myScoreSlider.value = playerScores[(int)playerID];
            UIManager.Instance.myScoreText.text = playerScores[(int)playerID].ToString();
        }
        else
        {
            UIManager.Instance.enemyScoreSlider.value = playerScores[(int)playerID];
            UIManager.Instance.enemyScoreText.text = playerScores[(int)playerID].ToString();
        }
    }

    public void ServerAddScore(uint playerID)
    {
        networkObject.SendRpc(RPC_ADD_SCORE, Receivers.AllBuffered, playerID);
    }

    public override void UpdatePlayerList(RpcArgs args)
    {
        while(playerScores.Count < networkObject.playerCount)
        {
            playerScores.Add(0);
        }
    }
}
