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

namespace Navigator.ViewModels
{
    public class GainLossSeriesViewModel : WorkspaceViewModel 
    {
      GainLossCompoundModelCollection gainLossCompoundModelCollection=null;
      private GainLossSeriesRenderer gainLossSeriesRenderer=new GainLossSeriesRenderer();
      private RelayCommand refreshCommand;
      private String chartTitle;
      private bool isRefreshing=false;
      private ObservableCollection<String> availableDays=new ObservableCollection<String>{"90","180","360","All"};
      private String selectedDays;
      private double changePercent=double.NaN;
      private bool showActivity = true;

    public GainLossSeriesViewModel()
    {
      Title="Gain/Loss Series";
      Initialize();
      PropertyChanged+=OnViewModelPropertyChanged;
      SelectedDays=availableDays[0];
    }

    private void OnViewModelPropertyChanged(object sender,PropertyChangedEventArgs eventArgs)
    {
      if (eventArgs.PropertyName.Equals("SelectedDays"))
      {
	      HandleSelectedDays();
      }
    }

    private void HandleSelectedDays()
    {
      IsBusy=true;
      ShowActivity=!IsRefreshing;
      Task workerTask = Task.Factory.StartNew(() =>
      {
        int days=-1;
        if(!("All".Equals(selectedDays)))days=int.Parse(selectedDays);

        ServiceResult serviceResult = MarketDataServiceClient.GetInstance().GetCompoundGainLoss(days);
        if (serviceResult.Success) 
        {
          gainLossCompoundModelCollection=(GainLossCompoundModelCollection)serviceResult.ContextSpecificResult;
          if(null!=gainLossCompoundModelCollection && 0!=gainLossCompoundModelCollection.Count)
          {
            gainLossSeriesRenderer.GainLossSeriesElements=GainLossSeriesModel.Elements(gainLossCompoundModelCollection);
            changePercent=GetChangePercent();
            if(!double.IsNaN(changePercent) && changePercent>=0)gainLossSeriesRenderer.SetColorGreen();
            else gainLossSeriesRenderer.SetColorRed();
            gainLossSeriesRenderer.Refresh();
            CreateChartTitle();
          }
        }
      });
      workerTask.ContinueWith((continuation) =>
      {
        IsBusy=false;
        IsRefreshing=false;
        ShowActivity=!IsRefreshing;
      });
    }

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

    public String SelectedDays
    {
      get
      {
        return selectedDays;
      }
      set
      {
        SetProperty(ref selectedDays,value);
      }
    }

    private void CreateChartTitle()
    {
      StringBuilder sb=new StringBuilder();
      if(double.IsNaN(changePercent))return;
      String strChangePercent=Utility.FormatPercent(changePercent);
      if(changePercent>=0)strChangePercent="+"+strChangePercent;
      sb.Append(String.Format("Gain/Loss {0} Thru {1} : ({2})",
        gainLossCompoundModelCollection[0].Date.ToShortDateString(),
        gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].Date.ToShortDateString(),
        strChangePercent));
      ChartTitle=sb.ToString();
    }

    private double GetChangePercent()
    {
      double changePercent=double.NaN;
      if(null == gainLossCompoundModelCollection || 0==gainLossCompoundModelCollection.Count)return changePercent;
      
      if(2>gainLossCompoundModelCollection.Count) return changePercent;
        double currentTotalGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-1].TotalGainLoss;
        double previousTotalGainLoss=gainLossCompoundModelCollection[gainLossCompoundModelCollection.Count-2].TotalGainLoss;
        if(previousTotalGainLoss>0)changePercent=(currentTotalGainLoss-previousTotalGainLoss)/previousTotalGainLoss;
      return changePercent;
    }

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

    public void Initialize()
    {
      Task workerTask=Task.Factory.StartNew(()=>
      {
      });
      workerTask.ContinueWith((continuation)=>
      {
      });
    }

    public IRenderer Renderer
    {
      get{return gainLossSeriesRenderer;}
    }

		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=>
          {
            HandleSelectedDays();
//            IsRefreshing=false;
          },param=>{return !IsRefreshing;});
        }
        return refreshCommand;
      }
    }
   }
}
