using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

using Prism.Mvvm;
using SPTrader.Models;
using apiwrappercli;
using Prism.Commands;
using apiwrappercli.poco.order;
using System.Windows;
using SPTrader.BusinessLayer;
using Prism.Events;
using apiwrappercli.poco;

namespace SPTrader.ViewModels
{
    public abstract class EditViewModel : BindableBase
    {
        private IEventAggregator ea = EventService.Instance.EventAggregator;
        protected SPApiProxyWrapper apiProxy;
        protected static readonly Int32 maxQty = 1000;

        #region
        protected SPOrder order;
        public SPOrder Order
        {
            get { return order; }
            set { SetProperty(ref order, value); }
        }

        private string priceStr = string.Empty;
        public string PriceStr
        {
            get { return priceStr; }
            set { SetProperty(ref priceStr, value); }
        }

        private int qty;
        public int Qty
        {
            get { return qty; }
            set { SetProperty(ref qty, value); }
        }

        private int selectedOrderType = 0;
        public int SelectedOrderType
        {
            get { return selectedOrderType; }
            set { SetProperty(ref selectedOrderType, value); }
        }

        private DateTime selectedDateTime = DateTime.Now;
        public DateTime SelectedDateTime
        {
            get { return selectedDateTime; }
            set { SetProperty(ref selectedDateTime, value); IsModified = true; }
        }

        private bool isModified = false;
        public bool IsModified
        {
            get { return isModified; }
            set { SetProperty(ref isModified, value); }
        }

        private bool isChangeClicked = false;
        public bool IsChangeClicked
        {
            get { return isChangeClicked; }
            set { SetProperty(ref isChangeClicked, value); }
        }

        protected int longticksize = 1;
        public int LongTickSize
        {
            get { return longticksize; }
            set { SetProperty(ref longticksize, value); }
        }

        protected sbyte decinprice = 0;
        public sbyte DecInPrice
        {
            get { return decinprice; }
            set { SetProperty(ref decinprice, value); }
        }
        #endregion

        protected string prodCode = string.Empty;
        protected OrderTypeEnum ordertype = OrderTypeEnum.Limit;

        public DelegateCommand ChangeCommand { get; private set; }
        public DelegateCommand ConfirmCommand { get; private set; }
        public DelegateCommand CancelCommand { get; private set; }

        public DelegateCommand<string> PriceCommand { get; private set; }
        public DelegateCommand<string> QtyCommand { get; private set; }

        public Action SetCancel { get; set; }
        public Action SetClose { get; set; }

        public abstract void SetOrderData(int ordno);
        protected abstract void PlaceEditOrder();
        public abstract void UpdatePrice(double price, int offset);

        public EditViewModel()
        {
            apiProxy = SPCLI.Instance.ApiProxyWrapper;            

            ChangeCommand = new DelegateCommand(OnChangeCommand);
            ConfirmCommand = new DelegateCommand(OnConfirmCommand);
            CancelCommand = new DelegateCommand(OnCancelCommand);
            PriceCommand = new DelegateCommand<string>(OnPriceCommand);
            QtyCommand = new DelegateCommand<string>(OnQtyCommand);
        }

        protected virtual void OnChangeCommand()
        {
            IsChangeClicked = true;
        }

        protected virtual void OnConfirmCommand()
        {
            PlaceEditOrder();

            // close window
            ea.GetEvent<ClosePendingDetailEvent>().Publish();
        }

        protected virtual void OnCancelCommand()
        {
            IsModified = false;
            IsChangeClicked = false;
            SetCancel?.Invoke();
        }

        protected virtual void OnPriceCommand(string sign)
        {
            IsModified = true;

            var dir = AdjustDirectionEnum.Up;

            if (!sign.Equals("+"))
                dir = AdjustDirectionEnum.Down;

            var res = apiProxy.UIHelper.AdjustInputPrice(PriceStr, prodCode, dir, 1, ordertype, false);

            if (res.Item1)
                PriceStr = res.Item3;
        }

        protected virtual void OnQtyCommand(string sign)
        {
            IsModified = true;

            var dir = AdjustDirectionEnum.Up;

            if (!sign.Equals("+"))
                dir = AdjustDirectionEnum.Down;

            var res = apiProxy.UIHelper.AdjustInputQty(Qty.ToString(), prodCode, dir, 1, ordertype, false, maxQty);

            if (res.Item1)
                Qty = res.Item2;
        }
    }
}