using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using DataDisplay.Renderers;
using MarketData.MarketDataModel;
using MarketData.Service;
using Navigator.Core;
using Navigator.MarketDataModel;
using Navigator.Renderers;
using Navigator.Utils;

namespace Navigator.ViewModels
{
    public class PremarketViewModel : WorkspaceViewModel
    {
        private RelayCommand refreshCommand;
        private PreMarketRenderer premarketRenderer=new PreMarketRenderer();
        private ObservableCollection<String> availableMarketDates;
        private ObservableCollection<String> availableMarkets;
        private List<PremarketElement> premarketDataCollection;
        private String selectedMarket;
        private String selectedMarketDate;
        private String chartTitle;
        private String companyName;
        private bool showActivity = true;

        private bool isRefreshing = false;

        public PremarketViewModel()
        {
            Title = "PreMarket";
            PropertyChanged += OnViewModelPropertyChanged;
            Initialize();
        }
        private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs eventArgs)
        {
			    if (eventArgs.PropertyName.Equals("SelectedMarket"))
				  {
				    HandleSelectedMarket();
				  }
          else if(eventArgs.PropertyName.Equals("SelectedMarketDate"))
          {
            HandleSelectedMarketDate(); 
          }
			  }

        private void HandleSelectedMarket()
        {
          IsBusy=true;
          Task workerTask = Task.Factory.StartNew(() =>
          {
            ServiceResult serviceResult = MarketDataServiceClient.GetInstance().GetAvailableMarketDates(selectedMarket);
            if (serviceResult.Success) 
            {
              List<DateTime> availableMarketDates=(List<DateTime>)serviceResult.ContextSpecificResult;
              List<String> availableMarketDatesStringList=new List<string>();
              foreach(DateTime date in availableMarketDates)availableMarketDatesStringList.Add(Utility.DateTimeToStringMMSDDSYYYY(date));
              AvailableMarketDates = new ObservableCollection<String>(availableMarketDatesStringList);
              if(null!=selectedMarketDate && AvailableMarketDates.Any(x=>x.Equals(selectedMarketDate)))
              {
                GetLatestPremarketData();
              }
            }
          });
          workerTask.ContinueWith((continuation) =>
          {
            IsBusy=false;
          });
        }

        private void HandleSelectedMarketDate()
        {
          GetLatestPremarketData();
        }

        private void GetLatestPremarketData()
        {
          IsBusy=true;
          ShowActivity=!IsRefreshing;
          Task workerTask = Task.Factory.StartNew(() =>
          {
            ServiceResult serviceResult = MarketDataServiceClient.GetInstance().GetLatestPremarketData(selectedMarket,Utility.ParseDate(selectedMarketDate));
            if (serviceResult.Success) 
            {
              premarketDataCollection = (List<PremarketElement>)serviceResult.ContextSpecificResult;
              if(null !=premarketDataCollection && 0!=premarketDataCollection.Count)
              {
                premarketRenderer.PreMarketElements=PreMarketModel.Elements(premarketDataCollection);
                if(premarketDataCollection[premarketDataCollection.Count-1].ChangePercent>0)premarketRenderer.SetColorGreen();
                else premarketRenderer.SetColorRed();
                premarketRenderer.Refresh();
                CreateChartTitle();
              }
            }
          });
          workerTask.ContinueWith((continuation) =>
          {
            IsBusy=false;
            IsRefreshing=false;
            ShowActivity=!IsRefreshing;
          });
        }

        private void CreateChartTitle()
        {
          StringBuilder sb=new StringBuilder();
          sb.Append(selectedMarket).Append(" Futures as of ").Append(selectedMarketDate);
          sb.Append("(");
          sb.Append(Utility.DateTimeToStringHHMMSS(premarketDataCollection.Min(x=>x.Timestamp)));
          sb.Append("-");
          sb.Append(Utility.DateTimeToStringHHMMSS(premarketDataCollection.Max(x=>x.Timestamp)));
          sb.Append(")");
          ChartTitle=sb.ToString();
        }

        public ObservableCollection<String> AvailableMarketDates
        {
            get { return availableMarketDates; }
            set { SetProperty(ref availableMarketDates, value); }
        }

        public ObservableCollection<String> AvailableMarkets
        {
            get { return availableMarkets; }
            set { SetProperty(ref availableMarkets, value); }
        }

        public String SelectedMarketDate
        {
          get
          {
            return selectedMarketDate;
          }
          set
          {
            SetProperty(ref selectedMarketDate,value);
          }
        }

        public String SelectedMarket
        {
          get
          {
            return selectedMarket;
          }
          set
          {
            SetProperty(ref selectedMarket,value);
          }
        }

        public void Initialize()
        {
          IsBusy=true;
          Task workerTask = Task.Factory.StartNew(() =>
          {
            ServiceResult serviceResult=MarketDataServiceClient.GetInstance().GetAvailableMarkets();
            if (serviceResult.Success)
            {
              AvailableMarkets=new ObservableCollection<string>((List<String>)serviceResult.ContextSpecificResult);
              if(null!=availableMarkets && 0!=availableMarkets.Count)SelectedMarket=availableMarkets[0];
            }
          });
          workerTask.ContinueWith((continuation) =>
          {
            IsBusy=false;
          });
        }

        public IRenderer Renderer
        {
          get{return premarketRenderer;}
        }

        public String ChartTitle
        {
          get { return chartTitle; }
          set { SetProperty(ref chartTitle, value); }
        }

        public String CompanyName
        {
          get { return companyName; }
          set { SetProperty(ref companyName, value); }
        }

        public bool IsRefreshing
        {
            get { return isRefreshing; }
            set { SetProperty(ref isRefreshing, value); }
        }
      // If the Refreshing Indicstor is showing we don't want to show the ControlTemplate indicator... but we do want the screen to shade while the operation runs
        public bool ShowActivity
        {
          get {return showActivity;}
          set {SetProperty(ref showActivity,value);}
        }
        public ICommand RefreshCommand
        {
            get
            {
                if (null == refreshCommand)
                {
                    refreshCommand = new RelayCommand(param =>
                    {
//                        HandleListViewSelectedItem();
                        GetLatestPremarketData();
 //                       IsRefreshing = false;
                    }, param => { return !IsRefreshing; });
                }
                return refreshCommand;
            }
        }
    }
}
