using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;

namespace BeWo.ViewModel.ListViewModel
{
    public class AccountingTransactionListVM : AbstractDCListMapperVM<AccountingTransactionDC, AccountingTransactionVM>
    {
        public static string PropertyName_FilterNode = "FilterNode";

        public static string PropertyName_FilterResult = "FilterResult";

        public static string PropertyName_FilterResultAmountSum = "FilterResultAmountSum";

        public static string PropertyName_FilterSpan = "FilterSpan";

        private SupportConceptTreeNodeDC _FilterNode;

        private BindingList<AccountingTransactionVM> _FilterResult;

        private DateTimeSpan _FilterSpan;

        public AccountingTransactionListVM(List<AccountingTransactionDC> pDCs) : base(pDCs)
        {
            base.VMList.ListChanged += (e, s) =>
                {
                    // _FilterResult = null;
                    this.FirePropertyChanged(PropertyName_FilterResult);
                };
        }

        public SupportConceptTreeNodeDC FilterNode
        {
            get { return this._FilterNode; }

            set
            {
                if (this.AreDifferent(this._FilterNode, value))
                {
                    this._FilterNode = value;
                    this._FilterResult = null;
                    this.FirePropertyChanged(PropertyName_FilterNode);
                    this.FirePropertyChanged(PropertyName_FilterResult);
                    this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
                }
            }
        }

        public BindingList<AccountingTransactionVM> FilterResult
        {
            get
            {
                if (this._FilterResult == null)
                {
                    IEnumerable<AccountingTransactionVM> lList = this.VMList;
                    this._FilterResult = new BindingList<AccountingTransactionVM>();

                    if (this._FilterSpan != null)
                    {
                        lList = lList.Where(vm => vm.BookingDate.Value.InBetween(this._FilterSpan, false));
                    }

                    if (this._FilterNode != null)
                    {
                        switch (this._FilterNode.NodeType)
                        {
                            case NodeType.SupportConcept:
                                lList = lList.Where(vm => vm.CostBearerRel != null && vm.CostBearerRel.SupportConcept.Equals(this._FilterNode.SupportConcept));
                                break;

                            case NodeType.SupportConceptCostBearerRelDC:
                                lList = lList.Where(vm => vm.CostBearerRel != null && vm.CostBearerRel.Equals(this._FilterNode.SupportConceptCostBearerRelDC));
                                break;
                        }
                    }

                    foreach (var item in lList)
                    {
                        this._FilterResult.Add(item);
                    }

                    // BindingList<AccountingTransactionVM> lResult = VMList;
                }

                return this._FilterResult;
            }
        }

        public decimal FilterResultAmountSum
        {
            get { return this.FilterResult.Sum(e => e.Amount.Value); }
        }

        public DateTimeSpan FilterSpan
        {
            get { return this._FilterSpan; }

            set
            {
                if (this.AreDifferent(this._FilterSpan, value))
                {
                    this._FilterSpan = value;
                    this._FilterResult = null;
                    this.FirePropertyChanged(PropertyName_FilterSpan);
                    this.FirePropertyChanged(PropertyName_FilterResult);
                    this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
                }
            }
        }

        protected override Comparison<AccountingTransactionVM> Comparison
        {
            get { return (x, y) => y.BookingDate.Value.CompareTo(x.BookingDate.Value); }
        }

        public void RefreshFilterResult()
        {
            this._FilterResult = null;
            this.FirePropertyChanged(PropertyName_FilterResult);
        }

        internal void UpdateSum()
        {
            this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
        }
    }
}