using System;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Rendering.Composition;
using CommunityToolkit.Mvvm.Input;
using MarketData;
using MarketData.DataAccess;
using MarketData.Generator.Interface;
using MarketData.MarketDataModel;
using MarketData.Utils;
using PortfolioManager.ViewModels;

namespace PortfolioManager.Dialogs
{
  public partial class ClosePositionDialogViewModel : DialogViewModelBase
  {
//    private IPosition sourcePosition;
    private IPurePosition sourcePosition;
    private String message = String.Empty;
    private bool okEnabled = false;

    public ClosePositionDialogViewModel(Window dialogWindow, IPurePosition clonedPosition)
    : base(dialogWindow)
    {
      sourcePosition = clonedPosition;
      if (Utility.IsEpoch(sourcePosition.SellDate))
      {
        sourcePosition.SellDate = DateTime.Now;
      }
      OkEnabled = Validate();
      DisplayName = "Close Position";
    }

    public String Symbol
    {
      get { return sourcePosition.Symbol; }
    }

    public String CompanyName
    {
      get
      {
        CompanyProfile companyProfile = CompanyProfileDA.GetCompanyProfile(sourcePosition.Symbol);
        return companyProfile.CompanyName;
      }
    }

    public String PurchaseDate
    {
      get
      {
        return sourcePosition.PurchaseDate.ToShortDateString();
      }
    }

    public String SellDate
    {
      get
      {
        return sourcePosition.SellDate.ToShortDateString();
      }
      set
      {
        try
        {
          sourcePosition.SellDate = Utility.ParseDate(value);
          base.OnPropertyChanged("SellDate");
          OkEnabled = Validate();
        }
        catch (Exception)
        {
          Message = "SellDate must be a valid date.";
        }
      }
    }

    public String SellPrice
    {
      get
      {
        return Utility.FormatCurrency(sourcePosition.CurrentPrice, 3);
      }
      set
      {
        try
        {
          sourcePosition.CurrentPrice = Utility.ParseCurrency(value);
          base.OnPropertyChanged("SellPrice");
          OkEnabled = Validate();
        }
        catch (Exception)
        {
          Message = "Sell price must be a valid number.";
        }
      }
    }

    [RelayCommand(CanExecute =nameof(Validate))]
    public async Task OkButtonClick()
    {
      IsSuccess = true;
      await Close();
    }

    [RelayCommand]
    public async Task CancelButtonClick()
    {
      await Close();
    }

    public IPurePosition GetResult()
    {
      return sourcePosition;
    }

    public String Message
    {
      get
      {
        return message;
      }
      set
      {
        message = value;
        base.OnPropertyChanged("Message");
      }
    }

    public void SetMessage(String message)
    {
      Message = message;
    }

    public bool OkEnabled
    {
      get
      {
        return okEnabled;
      }
      set
      {
        okEnabled = value;
        base.OnPropertyChanged("OkEnabled");
      }
    }

    private bool Validate()
    {
      DateGenerator dateGenerator = new DateGenerator();
      if (null == Symbol)
      {
        SetMessage("Invalid Symbol.");
        return false;
      }

      if (Utility.IsEpoch(sourcePosition.PurchaseDate))
      {
        SetMessage("Invalid Purchase Date.");
        return false;
      }

      if (Utility.IsEpoch(sourcePosition.SellDate))
      {
        SetMessage("Invalid Sell Date.");
        return false;
      }

      if (!dateGenerator.IsMarketOpen(sourcePosition.SellDate))
      {
        SetMessage("Market closed on Sell Date.");
        return false;
      }

      if (double.IsNaN(sourcePosition.CurrentPrice))
      {
        SetMessage("Invalid Sell Price.");
        return false;
      }

      SetMessage("");
      return true;
    }
  }
}