using System;
using System.Collections.ObjectModel;
using Aurora.Executors;
using Aurora.Design.Components.HostSelector;
using Aurora.Services;
using Xamarin.Forms;

namespace Aurora.Design.Views.Party
{
    enum PartyState
    {
        SelectingHost,
        InParty,
        Connecting,
    }

    public class PartyViewModel : BaseViewModel
    {
        private ObservableCollection<string> _members;

        private PartyState _state;

        private BaseExecutor _executor;

        private string _hostname;

        private string _port;


        public PartyViewModel()
        {
            _members = new ObservableCollection<string>()
            {
                "Kevin",
                "Brandon",
                "Sheila",
                "Dale",
                "Austin",
                "Tori",
                "Ashley",
                "Spencer",
            };
            OnPropertyChanged("Members");

            this.JoinCommand = new Command(OnJoinExecute, CanJoinExecute);
            this.HostCommand = new Command(OnHostExecute, CanHostExecute);

            State(PartyState.SelectingHost);
        }
        #region Properties

        public ObservableCollection<string> Members
        {
            get { return _members; }
            set { SetProperty(ref _members, value); }
        }

        public bool IsSelectingHost
        {
            get { return _state == PartyState.SelectingHost; }
        }

        public bool IsNotSelectingHost
        {
            get { return _state != PartyState.SelectingHost; }
        }

        public Command JoinCommand { get; set; }
        public Command HostCommand { get; set; }

        public string Hostname
        {
            get { return _hostname; }
            set { SetProperty(ref _hostname, value); }
        }

        public string Port
        {
            get { return _port; }
            set { SetProperty(ref _port, value); }
        }

        #endregion Properties


        private void State(PartyState state)
        {
            _state = state;
            OnPropertyChanged("IsSelectingHost");
        }

        #region Commands
        private void OnJoinExecute()
        {
            _executor = BaseExecutor.CreateExecutor<ClientExecutor>();
            Int32.TryParse(this.Port, out int intPort);
            _executor.Initialize();
            State(PartyState.Connecting);
        }

        private bool CanJoinExecute()
        {
            return true;
        }

        private void OnHostExecute()
        {
            Int32.TryParse(this.Port, out int intPort);
            //Init gRPC server
            ServerService.Instance.Initialize(this.Hostname, intPort);

            //Instantiate and initialize all executors
            _executor = BaseExecutor.CreateExecutor<HostExecutor>();
            _executor.Initialize();

            //start gRPC server

            ServerService.Instance.Start();

            //Change state
            State(PartyState.Connecting);
        }

        private bool CanHostExecute()
        {
            return true;
        }


        #endregion Commands

    }
}