using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

using BS.Shared;
using BS.Shared.DataContracts;

namespace BeWo.ViewModel.ListViewModel
{
    public class CostRatePeriodListVM : AbstractDCListMapperVM<CostRatePeriodDC, CostRatePeriodVM>
    {
        public CostRatePeriodListVM(List<CostRatePeriodDC> pCostRatePeriods) : base(pCostRatePeriods)
        {
            this.VMList.ListChanged += (s, e) =>
                {
                    if (e.ListChangedType != ListChangedType.ItemChanged)
                    {
                        this.FirePropertyChanged("GroupedByValueListEntry");
                    }
                };
        }

        public Dictionary<ValueListEntryDC, CostRatePeriodListVM> GroupedByValueListEntry
        {
            get
            {
                var result = this.VMList.Where(i => i.ValueListEntry != null).GroupBy(i => i.ValueListEntry).ToDictionary(g => g.Key, g => this);
                return result;
            }
        }

        public CostRatePeriodVM GetCurrentlyValidRate(CostRatePeriodType type)
        {
            var result = this.GetOldRates(type).OrderBy(i => i.EndDate).FirstOrDefault(i => i.EndDate >= DateTime.Now.Date);

            return result ?? this.GetLatestRate(type);
        }

        public CostRatePeriodVM GetCurrentlyValidRate(CostRatePeriodType type, ValueListEntryDC valueListEntry)
        {
            if (valueListEntry == null)
            {
                return this.GetCurrentlyValidRate(type);
            }

            var result = this.GetOldRates(type, valueListEntry).OrderBy(i => i.EndDate).FirstOrDefault(i => i.EndDate >= DateTime.Now.Date);

            return result ?? this.GetLatestRate(type, valueListEntry);
        }

        public CostRatePeriodVM GetLatestRate(CostRatePeriodType type)
        {
            CostRatePeriodVM latest = null;

            foreach (var item in VMList)
            {
                if (latest == null && item.CostRateType == type && item.ValueListEntry == null && !item.EndDate.HasValue)
                {
                    latest = item;
                }
            }

            return latest;

            //return this.VMList.SingleOrDefault(i => i.CostRateType == type && i.ValueListEntry == null && !i.EndDate.HasValue);
        }

        public CostRatePeriodVM GetLatestRate(CostRatePeriodType type, ValueListEntryDC valueListEntry)
        {
            if (valueListEntry == null)
            {
                return this.GetLatestRate(type);
            }
            
            CostRatePeriodVM latest = null;

            foreach (var item in VMList)
            {
                if (latest == null && item.CostRateType == type && item.ValueListEntry != null && item.ValueListEntry.ValueListEntryOid.Equals(valueListEntry.ValueListEntryOid) && !item.EndDate.HasValue)
                {
                    latest = item;
                }
            }

            return latest;
            


            //return
            //    this.VMList.SingleOrDefault(
            //        i => i.CostRateType == type && i.ValueListEntry != null && i.ValueListEntry.ValueListEntryOid.Equals(valueListEntry.ValueListEntryOid) && !i.EndDate.HasValue);
        }

        public BindingList<CostRatePeriodVM> GetOldRates(CostRatePeriodType type)
        {
            List<CostRatePeriodVM> list = new List<CostRatePeriodVM>();

            foreach (var item in VMList)
            {
                if (item.CostRateType == type && item.EndDate.HasValue && item.ValueListEntry == null)
                    list.Add(item);
            }
            list.Sort((x, y) => { return y.EndDate.Value.CompareTo(x.EndDate.Value); });
            return new BindingList<CostRatePeriodVM>(list);
            //return new BindingList<CostRatePeriodVM>(this.VMList.Where(i => i.CostRateType == type && i.EndDate.HasValue && i.ValueListEntry == null).ToList());
        }

        public BindingList<CostRatePeriodVM> GetOldRates(CostRatePeriodType type, ValueListEntryDC valueListEntry)
        {
            if (valueListEntry == null)
            {
                return this.GetOldRates(type);
            }
            List<CostRatePeriodVM> list = new List<CostRatePeriodVM>();

            foreach (var item in VMList)
            {
                if (item.CostRateType == type && item.EndDate.HasValue && item.ValueListEntry != null && item.ValueListEntry.ValueListEntryOid.Equals(valueListEntry.ValueListEntryOid))
                    list.Add(item);
            }
            list.Sort((x, y) => { return y.EndDate.Value.CompareTo(x.EndDate.Value); });
            return new BindingList<CostRatePeriodVM>(list);
            //return
            //    new BindingList<CostRatePeriodVM>(
            //        this.VMList.Where(i => i.CostRateType == type && i.EndDate.HasValue && i.ValueListEntry != null && i.ValueListEntry.ValueListEntryOid.Equals(valueListEntry.ValueListEntryOid)).
            //            ToList());
        }
    }
}