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

namespace Navigator.ViewModels
{
    public class BollingerBandViewModel : WorkspaceViewModel 
    {
      private RelayCommand refreshCommand;
      private int[] dayCountsList={60,90,135,180,360,720,1440};
      private int selectedDayCount=60;
      private bool isRefreshing=false;
      private BollingerBandRenderer bollingerBandRenderer=new BollingerBandRenderer();
      private List<String> symbols;
      private String selectedSymbol;
      private ObservableCollection<String> watchListSymbols;
      private List<BollingerBandElement> bollingerBands;
      private PortfolioTradesWithParityPrice portfolioTradesWithParityPrice;
      private String selectedWatchList="Valuations";
      private String chartTitle;
      private String companyName;
      private bool isSpecificNavigation=false;
      private bool showActivity = true;

      public BollingerBandViewModel()
      {
				Title = "Bollinger Bands";
        Item item = DataStore.GetItem("BollingerBandViewModelSymbol");
        isSpecificNavigation=null==item?false:true;

        Initialize();

			  PropertyChanged += OnViewModelPropertyChanged;
			  
			  if (isSpecificNavigation)
				{
				  selectedDayCount = dayCountsList[1];
				  DataStore.DeleteItem("BollingerBandViewModelSymbol");
          SelectedSymbol=item.Text;

          watchListSymbols=new ObservableCollection<String>();
          watchListSymbols.Add(item.Text);
          base.OnPropertyChanged("WatchListSymbols");

        }
      }
      private void OnViewModelPropertyChanged(object sender,PropertyChangedEventArgs eventArgs)
      {
        if(eventArgs.PropertyName.Equals("SelectedSymbol"))
        {
				  if(null==selectedSymbol)return;
          HandleBollingerBandRequest();
        }
        else if(eventArgs.PropertyName.Equals("SelectedDayCount"))
        {
				  if(null==selectedSymbol)return;
          HandleBollingerBandRequest();
        }
      }
      private void Initialize()
      {
        if(isSpecificNavigation)return;
        IsBusy=true;
        Task workerTask=Task.Factory.StartNew(()=>
        {
          ServiceResult serviceResult=MarketDataServiceClient.GetInstance().GetWatchList(selectedWatchList);
          if(serviceResult.Success)symbols=(List<String>)serviceResult.ContextSpecificResult;
          WatchListSymbols=new ObservableCollection<string>(symbols);
         
        });
        workerTask.ContinueWith((continuation)=>
        {
          IsBusy=false;
        });
      }
      public void HandleBollingerBandRequest()
      {
        ServiceResult serviceResult=null;
        IsBusy=true;
        ShowActivity=!IsRefreshing;
        Task workerTask=Task.Factory.StartNew(()=>
        {
          StopLimit stopLimit=null;
          serviceResult=MarketDataServiceClient.GetInstance().GetStopLimit(selectedSymbol);
          if(serviceResult.Success)stopLimit=(StopLimit)serviceResult.ContextSpecificResult;
          serviceResult = MarketDataServiceClient.GetInstance().GetPortfolioTradesWithParityPrice(selectedSymbol);
          if (serviceResult.Success) portfolioTradesWithParityPrice=(PortfolioTradesWithParityPrice)serviceResult.ContextSpecificResult;
          float change=float.NaN;
          Price currentPrice=null;
          serviceResult=MarketDataServiceClient.GetInstance().GetPrices(selectedSymbol,2);
          if(serviceResult.Success)
          {
            List<Price> prices=(List<Price>)serviceResult.ContextSpecificResult;
            if(null!=prices&&2==prices.Count)
            {
              Prices price2Day=new Prices(prices);
              change=price2Day.GetReturns()[0];
              currentPrice=prices[0];
            }
          }
          serviceResult=MarketDataServiceClient.GetInstance().GetBollingerBands(selectedSymbol,selectedDayCount);
          if(serviceResult.Success)bollingerBands=(List<BollingerBandElement>)serviceResult.ContextSpecificResult;
          serviceResult=MarketDataServiceClient.GetInstance().GetCompanyNameForSymbol(selectedSymbol);
          if(serviceResult.Success)
          {
            String companyName=(String)serviceResult.ContextSpecificResult;
            if(null!=companyName&&companyName.Length>40)companyName=companyName.Substring(0,35)+"...";
            CompanyName=companyName;
          }

          if(null!=bollingerBands&&0!=bollingerBands.Count)
          {
            StringBuilder sb=new StringBuilder();
            sb.Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBands.Min(x=>x.Date))).Append(" Thru ").Append(Utility.DateTimeToStringMMHDDHYYYY(bollingerBands.Max(x=>x.Date)));
            if(null!=currentPrice&&!float.IsNaN(change))
            {
              sb.Append(" (").Append(Utility.FormatCurrency(currentPrice.Close));
              sb.Append("/");
              sb.Append(" ").Append(Utility.FormatCurrency(currentPrice.Low));
              sb.Append(",");
              sb.Append(change>=0.00?"+":"").Append(Utility.FormatPercent((double)change));
              sb.Append(")");
            }
            ChartTitle=sb.ToString();
          }
          bollingerBandRenderer.PortfolioTradesWithParityPrice=portfolioTradesWithParityPrice;
          bollingerBandRenderer.K=BollingerBandModel.K(bollingerBands);
          bollingerBandRenderer.KL1=BollingerBandModel.KL1(bollingerBands);
          bollingerBandRenderer.L=BollingerBandModel.L(bollingerBands);
          bollingerBandRenderer.LP1=BollingerBandModel.LP1(bollingerBands);
          bollingerBandRenderer.SMAN=BollingerBandModel.SMAN(bollingerBands);
          bollingerBandRenderer.High=BollingerBandModel.High(bollingerBands);
          bollingerBandRenderer.Low=BollingerBandModel.Low(bollingerBands);
          bollingerBandRenderer.Close=BollingerBandModel.Close(bollingerBands);
          bollingerBandRenderer.StopLimit=stopLimit;
          bollingerBandRenderer.Refresh();
        });
        workerTask.ContinueWith((TaskContinuationOptions)=>
        {
          IsBusy=false;
          IsRefreshing=false;
          ShowActivity=!IsRefreshing;
        });
      }
      public ObservableCollection<String> WatchListSymbols
      {
        get{return watchListSymbols;}
        set{SetProperty(ref watchListSymbols,value);}
      }
      public IRenderer Renderer
      {
        get{return bollingerBandRenderer;}
      }
      public String SelectedSymbol
      {
        get{return selectedSymbol;}
        set{SetProperty(ref selectedSymbol,value);}
      }
    public String ChartTitle
    {
      get { return chartTitle; }
      set { SetProperty(ref chartTitle, value); }
    }
    public String CompanyName
    {
      get { return companyName; }
      set { SetProperty(ref companyName, value); }
    }
    public int SelectedDayCount
      {
        get{return selectedDayCount;}
        set{SetProperty(ref selectedDayCount,value);}
      }
      public int[] DayCountsList
      {
        get{return dayCountsList;}
        private set{;}
      }
      // 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 bool IsRefreshing
      {
        get{return isRefreshing;}
        set{SetProperty(ref isRefreshing,value);}
      }
      public ICommand RefreshCommand
      {
        get
        {
          if(null==refreshCommand)
          {
            refreshCommand=new RelayCommand(param=>
            {
              HandleBollingerBandRequest();
//              IsRefreshing=false;
            },param=>{return !IsRefreshing;});
          }
          return refreshCommand;
        }
      }
    }
}