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

using BeWo.Validation;
using BeWo.ViewModel.ListViewModel;

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

using DevExpress.Xpf.Editors.Helpers;

namespace BeWo.ViewModel
{
    public class BargeldkassenVM : AbstractDCMapperVM<BargeldkassenDC>
    {
        public static string PropertyName_Kassenname           = "Kassenname";
        public static string PropertyName_ObjectOid            = "ObjectOid";
        public static string PropertyName_ObjectTid            = "ObjectTid";
        public static string PropertyName_Bargeldtransaktionen = "Bargeldtransaktionen";
        public static string PropertyName_Auszahlungsintervall = "Auszahlungsintervall";

        private string                          _Kassenname;
        private long?                           _ObjectOid;
        private TableID                         _ObjectTid;
        private BargeldtransaktionsListVM       _Bargeldtransaktionen;
        private EnumValue<Auszahlungsintervall> _Auszahlungsintervall;

        public BargeldkassenVM(BargeldkassenDC pDC) : base(pDC, pDC.BargeldkassenOid == null) { }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public string Kassenname
        {
            get { return _Kassenname; }

            set
            {
                if (AreDifferent(_Kassenname, value))
                {
                    _Kassenname = value;
                    StoreDirtyInformation(AreDifferent(DataContract.Kassenname, value), PropertyName_Kassenname);
                    FirePropertyChanged(PropertyName_Kassenname);
                }
            }
        }

        public long? ObjectOid
        {
            get { return _ObjectOid; }

            set
            {
                if (AreDifferent(_ObjectOid, value))
                {
                    _ObjectOid = value;
                    StoreDirtyInformation(AreDifferent(DataContract.ObjectOid, value), PropertyName_ObjectOid);
                    FirePropertyChanged(PropertyName_ObjectOid);
                }
            }
        }

        public TableID ObjectTid
        {
            get { return _ObjectTid; }

            set
            {
                if (AreDifferent(_ObjectTid, value))
                {
                    _ObjectTid = value;
                    StoreDirtyInformation(AreDifferent(DataContract.ObjectTid, value), PropertyName_ObjectTid);
                    FirePropertyChanged(PropertyName_ObjectTid);
                }
            }
        }

        public BargeldtransaktionsListVM Bargeldtransaktionen
        {
            get { return _Bargeldtransaktionen; }

            set
            {
                    _Bargeldtransaktionen = value;

                    FirePropertyChanged(PropertyName_Bargeldtransaktionen);
            }
        }

        public decimal Kassenbestand
        {
            get
            {
				//var kassenbestand = Bargeldtransaktionen.VMList.OrderByDescending(o => o.Zahlungreturn kassenbestand != null ? kassenbestand.Transaktionskassenbestand.Value : 0m;sdatum).ThenByDescending(t => t.DataContract.BargeldtransaktionOid).FirstOrDefault();
				//return kassenbestand != null ? kassenbestand.Transaktionskassenbestand.Value : 0m;
	            var ein =
		            Bargeldtransaktionen.VMList.Where(t => t.Zahlungstyp.Enum == Zahlungstyp.Einzahlung).Sum(t => t.Betrag) ??
		            0m;
	            var aus =
		            Bargeldtransaktionen.VMList.Where(t => t.Zahlungstyp.Enum == Zahlungstyp.Auszahlung).Sum(t => t.Betrag) ??
		            0;

	            return ein - aus;
            }
        }

        [Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
        public EnumValue<Auszahlungsintervall> Auszahlungsintervall
        {
            get { return _Auszahlungsintervall; }
            set
            {
                if (AreDifferent(_Auszahlungsintervall, value))
                {
                    _Auszahlungsintervall = value;
                    StoreDirtyInformation(AreDifferent(DataContract.Auszahlungsintervall, value), PropertyName_Auszahlungsintervall);
                    FirePropertyChanged(PropertyName_Auszahlungsintervall);
                }
            }
        }

        public void RecalculateTransaktionsbestaende()
        {
            var liste = Bargeldtransaktionen.VMList.OrderBy(o => o.Zahlungsdatum).ThenBy(t => t.DataContract.BargeldtransaktionOid);

            liste.ForEach(f => f.Transaktionskassenbestand = 0);

            var vorherige = liste.FirstOrDefault();
            if (vorherige != null)
            {
                foreach (var transaktion in liste)
                {
                    transaktion.Transaktionskassenbestand = vorherige.Transaktionskassenbestand + transaktion.Betrag*(transaktion.Zahlungstyp.Enum == Zahlungstyp.Auszahlung ? -1 : 1);
                    vorherige = transaktion;
                }
            }
        }

        protected override void InitByDataContract(BargeldkassenDC pDataContract)
        {
            if (!IsNew)
            {
                _Kassenname = pDataContract.Kassenname;
                _ObjectOid = pDataContract.ObjectOid;
                _ObjectTid = pDataContract.ObjectTid;
                _Auszahlungsintervall = new EnumValue<Auszahlungsintervall>(pDataContract.Auszahlungsintervall, EnumTranslations.AllTranslations[pDataContract.Auszahlungsintervall]);
            }

            Bargeldtransaktionen = VMFactory.CreateBargeldtransaktionsListVM(pDataContract.Bargeldtransaktionen ?? (pDataContract.Bargeldtransaktionen = new List<BargeldtransaktionDC>()));
        }

        protected override BargeldkassenDC MapToDataContract(BargeldkassenDC pDataContract, bool doCommit)
        {
            pDataContract.Kassenname           = _Kassenname;
            pDataContract.ObjectOid            = _ObjectOid;
            pDataContract.ObjectTid            = _ObjectTid;
            pDataContract.Auszahlungsintervall = _Auszahlungsintervall.Enum;

            pDataContract.Bargeldtransaktionen = _Bargeldtransaktionen.CopyToDCList(doCommit);

            return pDataContract;
        }

        public override string ToString()
        {
            return Kassenname;
        }
    }
}