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

using BeWo.ViewModel.ListViewModel;

using BS.Shared.Core;
using BS.Shared.DataContracts.Compact;

namespace BeWo.ViewModel
{
    public class ServiceInvoiceViewVM : INotifyPropertyChanged
    {
        #region Constants and Fields

        public static string PropertyName_InvoicePeriodEnd = "InvoicePeriodEnd";

        public static string PropertyName_InvoicePeriodStart = "InvoicePeriodStart";

        public static string PropertyName_IsAllSupportConcepts = "IsAllSupportConcepts";

        public static string PropertyName_IsSelectionValid = "IsSelectionValid";

        public static string PropertyName_IsUseApprovalPeriod = "IsUseApprovalPeriod";

        public static string PropertyName_SelectedCostBearer = "SelectedCostBearer";

        public static string PropertyName_SelectedSupportConcept = "SelectedSupportConcept";

        public static string PropertyName_ServiceInvoiceListVM = "ServiceInvoiceListVM";

        private DateTime? _InvoicePeriodEnd;

        private DateTime? _InvoicePeriodStart;

        private bool _IsAllSupportConcepts;

        private bool _IsUseApprovalPeriod;

        private CompactOrganisationDC _SelectedCostBearer;

        private CompactSupportConceptDC _SelectedSupportConcept;

        private ServiceInvoiceListVM _ServiceInvoiceListVM;

        #endregion

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        public DateTime? InvoicePeriodEnd
        {
            get
            {
                return this._InvoicePeriodEnd;
            }

            set
            {
                this._InvoicePeriodEnd = value;
                this.FirePropertyChanged(PropertyName_InvoicePeriodEnd);
                this.FirePropertyChanged(PropertyName_IsSelectionValid);
            }
        }

        public DateTime? InvoicePeriodStart
        {
            get
            {
                return this._InvoicePeriodStart;
            }

            set
            {
                this._InvoicePeriodStart = value;
                this.FirePropertyChanged(PropertyName_InvoicePeriodStart);
                this.FirePropertyChanged(PropertyName_IsSelectionValid);
            }
        }

        public bool IsAllSupportConcepts
        {
            get
            {
                return this._IsAllSupportConcepts;
            }

            set
            {
                if (!value.Equals(this._IsAllSupportConcepts))
                {
                    this._IsAllSupportConcepts = value;
                    this.FirePropertyChanged(PropertyName_IsAllSupportConcepts);
                    this.FirePropertyChanged(PropertyName_IsSelectionValid);
                }
            }
        }

        public bool IsSelectionValid
        {
            get
            {
                return this.SelectedCostBearer != null
                       && (this.SelectedSupportConcept != null || this.IsAllSupportConcepts)
                       && (this.IsUseApprovalPeriod || (this.InvoicePeriodStart.HasValue && this.InvoicePeriodEnd.HasValue));
            }
        }

        public bool IsUseApprovalPeriod
        {
            get
            {
                return this._IsUseApprovalPeriod;
            }

            set
            {
                if (!value.Equals(this._IsUseApprovalPeriod))
                {
                    this._IsUseApprovalPeriod = value;
                    this.FirePropertyChanged(PropertyName_IsUseApprovalPeriod);
                    this.FirePropertyChanged(PropertyName_IsSelectionValid);
                }
            }
        }

        public CompactOrganisationDC SelectedCostBearer
        {
            get
            {
                return this._SelectedCostBearer;
            }

            set
            {
                this._SelectedCostBearer = value;
                this.FirePropertyChanged(PropertyName_SelectedCostBearer);
                this.FirePropertyChanged(PropertyName_IsSelectionValid);
            }
        }

        public CompactSupportConceptDC SelectedSupportConcept
        {
            get
            {
                return this._SelectedSupportConcept;
            }

            set
            {
                this._SelectedSupportConcept = value;
                this.FirePropertyChanged(PropertyName_SelectedSupportConcept);
                this.FirePropertyChanged(PropertyName_IsSelectionValid);
            }
        }

        public ServiceInvoiceListVM ServiceInvoiceListVM
        {
            get
            {
                return this._ServiceInvoiceListVM;
            }

            set
            {
                this._ServiceInvoiceListVM = value;
                this.FirePropertyChanged(PropertyName_ServiceInvoiceListVM);
            }
        }

        #endregion

        #region Methods

        internal List<long> GetIsPrintingIds()
        {
            return this.ServiceInvoiceListVM.VMList
                .Where(i => i.IsPrinting && !i.IsNew).Select(i => i.DataContract.ServiceInvoiceOid.Value)
                .ToList();
        }

        internal DateTimeSpan GetPeriodSpan()
        {
            DateTimeSpan period = null;
            if (!this.IsUseApprovalPeriod)
            {
                period = new DateTimeSpan
                         {
                             StartDateTime = this.InvoicePeriodStart.Value.Date, 
                             EndDateTime = this.InvoicePeriodEnd.Value.Date
                         };
            }

            return period;
        }

        internal long? GetSupportConceptOid()
        {
            long? supportConceptOid = null;
            if (!this.IsAllSupportConcepts && this.SelectedSupportConcept != null)
            {
                supportConceptOid = this.SelectedSupportConcept.SupportConceptOid;
            }

            return supportConceptOid;
        }

        private void FirePropertyChanged(string name)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        #endregion
    }
}