﻿using AsmodeeDigital.Common.Plugin.Domain.Players;
using AsmodeeDigital.Common.Plugin.Utils;
using AsmodeeDigital.PlayReal.Plugin.Manager;
using AsmodeeDigital.PlayReal.Samples.Logic;
using AsmodeeDigital.PlayReal.Samples.UI.LobbyPlayers;
using com.daysofwonder;
using com.daysofwonder.async;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace AsmodeeDigital.PlayReal.Samples.Views
{
    /// <summary>
    /// View displayed when game start
    /// </summary>
    public class MainMenuView : MonoBehaviour
    {
        /// <summary>
        /// UI references of MainMenuView
        /// </summary>
        [Serializable]
        public class UI
        {
            public Text WelcomeText;
            public Button EnterLobbyButton;

            public List<PlayerToggle> PlayersToggle;
            public ToggleGroup PlayersToggleGroup;
        }

        /// <summary>
        /// UI instance
        /// </summary>
        public UI ui;

        /// <summary>
        /// List of sample users
        /// </summary>
        public List<User> Users = new List<User>();

        /// <summary>
        /// Logic of the view
        /// </summary>
        private MainMenuLogic _mainMenuLogic;

        private int _indexUser = 0;

        private void Start()
        {
            Init();
        }

        /// <summary>
        /// Initialize the view - Creating logic - Creating .Net events
        /// If the game is started with user1 or user2 in command line, the window is located in right (user1) corner or left (user2) corner of 2nd monitor (left)
        /// </summary>
        private void Init()
        {
            _mainMenuLogic = new MainMenuLogic(PlayRealManager.Instance.ServerConnection, PlayRealManager.Instance.Persistence);
            _mainMenuLogic.LogEnabled = PlayRealManager.Instance.LogLogicEnabled;

            _mainMenuLogic.ConnectedToServerEvent += MainMenuLogic_ConnectedToServerEvent;
            _mainMenuLogic.DisconnectedFromServerEvent += MainMenuLogic_DisconnectedFromServerEvent;
            _mainMenuLogic.AuthenticatedEvent += MainMenuLogic_AuthenticatedEvent;

            _mainMenuLogic.Init();

            AutoConnect();
        }

        #region UI interactions
        public void PlayerToggle_OnValueChanged(bool isOn)
        {
            if (isOn)
            {
                PlayerToggle playerToggle = ui.PlayersToggle.Find(pt => pt.ui.Toggle.isOn);

                if (!PlayRealManager.Instance.ServerConnection.IsConnected)
                {
                    Connect();
                }
                else
                {
                    if (playerToggle != null)
                    {
                        _indexUser = playerToggle.Index;

                        _mainMenuLogic.Disconnect();
                    }
                }
            }
        }

        /// <summary>
        /// Call the logic to connect user
        /// </summary>
        public void Connect()
        {
            _mainMenuLogic.Connect();
        }

        /// <summary>
        /// AutoConnnect checkbox value changed
        /// </summary>
        /// <param name="isOn"></param>
        public void AutoConnect_OnChanged(bool isOn)
        {
            PlayerPrefs.SetInt("AutoConnect", isOn ? 1 : 0);
            PlayerPrefs.SetInt("IndexUser", _indexUser);
            PlayerPrefs.Save();
        }

        /// <summary>
        /// Call the logic to show the LobbyView
        /// </summary>
        public void ShowLobbyView()
        {
            _mainMenuLogic.ShowLobbyView();
        }
        #endregion

        #region Private methods
        /// <summary>
        /// Auto connect to the previous connected user. By default to Alice Account under Unity Editor.
        /// If the application is launched with user1 or user2 in command line it connect to Bob or Carol
        /// </summary>
        private void AutoConnect()
        {
            for (int i = 0; i < 3; i++)
            {
                ui.PlayersToggle[i].DoWId = Users[i].DoWID;
            }

            if (PlayRealManager.Instance.Persistence.ConnectedPlayer == null)
            {
                _indexUser = PlayerPrefs.GetInt("IndexUser", 0);

#if UNITY_EDITOR
                _indexUser = 0;
#endif

                //--- Debug from command line
#if UNITY_STANDALONE
                if (Environment.CommandLine.Contains("user1"))
                    _indexUser = 1;
                else if (Environment.CommandLine.Contains("user2"))
                    _indexUser = 2;
#endif
                //---

                if (_indexUser != -1)
                {
                    ui.PlayersToggle[_indexUser].ui.Toggle.isOn = true;
                }
                //---
            }
            else
            {
                ShowConnnectedPlayer(PlayRealManager.Instance.Persistence.ConnectedPlayer);
            }
        }

        /// <summary>
        /// Show a connected friend
        /// </summary>
        /// <param name="player">Connected friend</param>
        private void ShowConnnectedPlayer(Player player)
        {
            ui.WelcomeText.gameObject.SetActive(true);
            ui.WelcomeText.text = String.Format("Welcome back {0}", player.name);
            ui.EnterLobbyButton.interactable = true;

            PlayerToggle playerToggle = ui.PlayersToggle.Find(pt => pt.DoWId == player.w_w_w_id);

            ui.PlayersToggle.ForEach(pt => pt.Deselect());
            playerToggle.Select();

            if (!String.IsNullOrEmpty(player.avatar.image))
            {
                StartCoroutine(TextureLoader.LoadTexture(String.Format("http://www.daysofwonder.com/images/avatars/{0}", player.avatar.image), playerToggle.ui.Avatar));
            }
        }
        #endregion

        #region Logic events callbacks
        /// <summary>
        /// Event called when the user is connected to DoW server. Authenticate the user
        /// </summary>
        private void MainMenuLogic_ConnectedToServerEvent()
        {
            User user = Users[_indexUser];

            _mainMenuLogic.AuthenticateUser(user.Login, user.Password);
        }

        /// <summary>
        /// Event called when the user is disconnected from DoW server
        /// </summary>
        private void MainMenuLogic_DisconnectedFromServerEvent()
        {
            ui.WelcomeText.gameObject.SetActive(false);
            ui.EnterLobbyButton.interactable = false;

            ui.PlayersToggle.ForEach(pt => pt.Deselect());

            Connect();
        }

        /// <summary>
        /// Event called when the user is authenticated to DoW server
        /// </summary>
        /// <param name="asyncConnectedRequest"></param>
        private void MainMenuLogic_AuthenticatedEvent(AsyncConnectedRequest asyncConnectedRequest)
        {
            ShowConnnectedPlayer(asyncConnectedRequest.player);
        }
        #endregion

        /// <summary>
        /// Dispose events and logic
        /// </summary>
        private void OnDestroy()
        {
            _mainMenuLogic.ConnectedToServerEvent -= MainMenuLogic_ConnectedToServerEvent;
            _mainMenuLogic.DisconnectedFromServerEvent -= MainMenuLogic_DisconnectedFromServerEvent;
            _mainMenuLogic.AuthenticatedEvent -= MainMenuLogic_AuthenticatedEvent;

            _mainMenuLogic.Dispose();
        }
    }
}