using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

namespace Networking.Client
{
    [CreateAssetMenu(menuName = "Major Project/Networking/ClientObject", order = 150)]
    public class ClientObject : ScriptableObject
    {

        #region Inspector Fields
        [Header("Connection Settings")]
        [SerializeField]
        [Tooltip("Server Address to Connect to")]
        private string ServerIP;

        [SerializeField]
        [Tooltip("Port to connect on")]
        private int Port;

        [SerializeField]
        [Tooltip("Scene to return to if disconnected from server")]
        private string DisconnectScene;

        [Header("Player Settings")]
        [SerializeField]
        [Tooltip("Player Name")]
        private string DisplayName;

		[SerializeField]
		[Tooltip("Player Animal")]
		private string PlayerAnimal;

        [SerializeField]
        [Tooltip("Player Color")]
		private Color PlayerColor;

        [Header("Run Time Settings")]
        [SerializeField]
        [Tooltip("Client Inventory")]
        protected Inventory Inventory;

        [SerializeField]
        [Tooltip("Current Time in Round")]
        public float RoundTime;

        [SerializeField]
        [Tooltip("Current Score in Round")]
        public float RoundScore;

        #endregion Inspector Fields


        #region ReadOnly Variables
        public NetworkClient client { get; private set; }
        public bool isConnected { get { return client != null && client.isConnected; } }
        #endregion ReadOnly Variables


        public void Connect(string serverAddress,int port)
        {
            Debug.Log("Connecting to server: " + serverAddress + ", " + port);
            this.ServerIP = serverAddress;
            this.Port = port;
            client = new NetworkClient();
            client.Configure(TransportConfigure.CreateConfigure(), 1);

            client.Connect(serverAddress, port);

            Inventory.Reset();

            client.RegisterHandler(LogicProtocols.SendInventory, RecieveInventory);
            client.RegisterHandler(LoginProtocols.SceneChange, RecieveSceneChange);
            client.RegisterHandler(MsgType.Disconnect, OnDisconnect);
            client.RegisterHandler(LogicProtocols.SendRoundTime, UpdateTime);
            client.RegisterHandler(LogicProtocols.SendScore, UpdateScore);
        }

        public void Stop()
        {
            client.Disconnect();
        }

        public void UpdatePlayerDetails(string DisplayName, Color PlayerColor, string PlayerAnimal)
        {
			this.PlayerAnimal = PlayerAnimal;
            this.DisplayName = DisplayName;
            this.PlayerColor = PlayerColor;
        }


        public void RecieveInventory(NetworkMessage msg)
        {
            Debug.Log("Recieving Inventory");
            LogicProtocols.InventoryMsg inventoryMsg;
            if (!msg.TryRead(out inventoryMsg))
                return;

            Inventory.SetItems(inventoryMsg.bagItems);
        }

        public void RecieveSceneChange(NetworkMessage msg)
        {
            LoginProtocols.SceneMsg sceneMsg;
            if (!msg.TryRead(out sceneMsg))
                return;

            //Additive or single
            UnityEngine.SceneManagement.LoadSceneMode mode = sceneMsg.Additive ? UnityEngine.SceneManagement.LoadSceneMode.Additive : UnityEngine.SceneManagement.LoadSceneMode.Single;

            UnityEngine.SceneManagement.SceneManager.LoadScene(sceneMsg.Scene, mode);
        }

        public void OnDisconnect(NetworkMessage msg)
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene(DisconnectScene);
        }

        public void UpdateTime(NetworkMessage msg)
        {
            LogicProtocols.FloatMsg floatMsg;
            if (!msg.TryRead(out floatMsg))
                return;

            RoundTime = floatMsg.Float;
        }

        public void UpdateScore(NetworkMessage msg)
        {
            LogicProtocols.FloatMsg floatMsg;
            if (!msg.TryRead(out floatMsg))
                return;

            RoundScore = floatMsg.Float;
        }
    }

}
