using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using BeWo.Core;
using BeWo.Core.Service;
using BeWo.ServiceProxy;
using BeWo.Validation;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;

using BS.Shared;
using BS.Shared.Services;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;

namespace BeWo.View.Detail
{
    /// <summary>
    /// Interaktionslogik für ServiceRecordEditView.xaml
    /// </summary>
    public partial class ServiceRecordGroupEditView : BeWoView
    {
        private ServiceRecordGroupDC _Group;

        private ServiceCategoryDC _OldCategory;

        private ServiceDescriptionDC _OldServiceDescription;

        private ServiceRecordVM _ServiceRecordVM;


        public ServiceRecordGroupEditView()
        {
            InitializeComponent();

            Loaded += loaded;
        }

        private void loaded(object sender, RoutedEventArgs e)
        {
            var x = ActualWidth;
        }

        public override bool CanDelete
        {
            get
            {
                return false;
            }
        }

        public override bool IsDirty
        {
            get
            {
                if (this.IsSupportConceptOrEmployeeChanged())
                {
                    return true;
                }

				return _ServiceRecordVM != null && _ServiceRecordVM.IsDirty;
            }
        }

        public override string SaveObjectName
        {
            get
            {
                return "dieser Gruppenbuchung";
            }
        }

        public override string Title
        {
            get
            {
                return "Gruppenbuchung bearbeiten";
            }
        }

        private ServiceRecordListVM ViewModel { get; set; }

        public void InitView(ServiceRecordListVM pListViewModel, ServiceRecordVM pSelectedViewModel, ServiceRecordGroupDC group)
        {
            InitializeComponent();
            Loaded += ServiceRecordGroupEditView_Loaded;
            if (BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowCreateServiceRecordsForAllClients))
            {
                // chkShowAllClients.IsChecked = showAllCustomer;
            }
            else
            {
                // chkShowAllClients.IsChecked = false;
                // chkShowAllClients.Visibility = Visibility.Collapsed;
            }

            // chkShowOldSupportConcepts.IsChecked = showOldSupportConcepts;
			_ServiceRecordVM = pSelectedViewModel;
            
            _Group = group;

			_OldCategory = _ServiceRecordVM.Category;
			_OldServiceDescription = _ServiceRecordVM.ServiceDescription;

			DataContext = _ServiceRecordVM;

            ViewModel = pListViewModel;

			numerictb_distance.Visibility = BeWoApp.AppSettings.ShowDistanceFields ? Visibility.Visible : Visibility.Collapsed;
			lblDistance.Visibility = BeWoApp.AppSettings.ShowDistanceFields ? Visibility.Visible : Visibility.Collapsed;

            // this.customerComboBox.ItemsSource = _FlatSupportConceptItems;
            //this.numerictb_duration.EditValueChanged += (s, e) =>
            //    {
            //        if (string.IsNullOrEmpty(this.numerictb_duration.Text))
            //        {
            //            this.numerictb_duration.Value = 0;
            //        }
            //    };

            Focus();
            TextboxNotice.Focus();

			_ServiceRecordVM.Category = _OldCategory;
			_ServiceRecordVM.ServiceDescription = _OldServiceDescription;
			_ServiceRecordVM.SetDirty(false);
 
            ConfigureDocTypes();
            InitSelectionList();
            isEndDateVisible();
        }

        private void isEndDateVisible()
        {

            var Settings = BeWoApp.AppSettings;

            if (Settings.IsEndDateVisible)
            {
                datepicker_newEndDate.Visibility = Visibility.Visible;
                EndDateLabel.Visibility = Visibility.Visible;  
            }
            else
            {
                datepicker_newEndDate.Visibility = Visibility.Collapsed;
                EndDateLabel.Visibility = Visibility.Collapsed;
            }
        }





        public bool IsCustomerChangeAllowed()
        {
            // FlatSupportConceptTreeNodeDC selectedNode = ViewModel.SelectedVMForEditing.ChoosenNode;
            bool lAllowed = true;

            // if (_OriginalVM.Customer != null && selectedNode.SupportConceptTreeNodeDC.Customer != null &&
            // _OriginalVM.Customer.CustomerOid != selectedNode.SupportConceptTreeNodeDC.Customer.CustomerOid)
            // {
            // if (MessageBox.Show("Möchten Sie diese Leistung wirklich auf Klient " +
            // selectedNode.SupportConceptTreeNodeDC.Customer.FirstName + " " + selectedNode.SupportConceptTreeNodeDC.Customer.LastName +
            // " umbuchen?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
            // lAllowed = false;
            // }
            // else if (_OriginalVM.SupportConcept != null && selectedNode.SupportConceptTreeNodeDC.SupportConcept != null &&
            // _OriginalVM.SupportConcept.SupportConceptOid != selectedNode.SupportConceptTreeNodeDC.SupportConcept.SupportConceptOid)
            // {
            // if (MessageBox.Show("Möchten Sie diese Leistung wirklich auf einen anderen Hilfeplan umbuchen?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
            // lAllowed = false;
            // }
            // else if (_OriginalVM.CostBearer != null && selectedNode.SupportConceptTreeNodeDC.CostBearer != null &&
            // _OriginalVM.CostBearer.CostBearerOid != selectedNode.SupportConceptTreeNodeDC.CostBearer.CostBearerOid)
            // {
            // if (MessageBox.Show("Möchten Sie diese Leistung wirklich auf den Kostenträger " +
            // selectedNode.SupportConceptTreeNodeDC.CostBearer.Name +
            // " umbuchen?", "Speichern", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
            // lAllowed = false;
            // }
            return lAllowed;
        }

		public bool IsValid()
		{
			
			bool lValid = true;

			if (this.multiSupportConceptControl.SelectedSupportConcepts.Count == 0)
			{
				MessageBox.Show("Bitte wählen Sie mindestens einen Hilfeplan aus.", "Speichern", MessageBoxButton.OK, MessageBoxImage.Information);
				return false;
			}

			if (lValid)
			{
				if (this.multiEmployeeControl.SelectedEmployees.Count == 0)
				{
					MessageBox.Show("Bitte wählen Sie mindestens einen Mitarbeiter aus.", "Speichern", MessageBoxButton.OK, MessageBoxImage.Information);
					return false;
				}
			}

			if (BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed > 0)
			{
				if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecord_AllowEditAfterMaxDaysInNextMonth))
				{
					if (_ServiceRecordVM.StartDate.HasValue)
					{
						DateTime dt = new DateTime(_ServiceRecordVM.StartDate.Value.Year, _ServiceRecordVM.StartDate.Value.Month, 1);
						dt = dt.AddMonths(1);
						dt = dt.AddDays(BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed);
						if (DateTime.Now >= dt)
						{
							MessageBox.Show(
								"Sie können keine neuen Leistungen für den " + _ServiceRecordVM.StartDate.Value.ToShortDateString() +
								" dokumentieren, da bereits der " + BeWoApp.AppSettings.MaxDaysEditServiceRecordsAllowed +
								". des nachfolgenden Monats überschritten ist.", "Speichern", MessageBoxButton.OK,
								MessageBoxImage.Information);
							lValid = false;
						}
					}
				}
			}

			return ValidationTrigger.Validate(this.rootGrid) && lValid;
		}

		

        internal override bool DoSaveCheck()
        {
            if (this.IsDirty)
            {
                MessageBoxResult lResult = this.ShowSaveQuestion();
                if (lResult == MessageBoxResult.Cancel)
                {
                    this.Focus();
                    return false;
                }

                if (lResult == MessageBoxResult.Yes)
                {
                    if (!this.IsCustomerChangeAllowed())
                    {
                        return false;
                    }
                    if (IsValid())
                        this.SaveData();
                    else
                        return false;
                }
            }

            return true;
        }

        protected override void Save()
        {
            if (!IsDirty) 
                return;

            
            UpdateServiceRecordGroup();

			ServiceRecordDC dc = _ServiceRecordVM.CommitToDataContract();

            // Runden
            bool roundDuration = true;
            int minuteInterval = 0;

            CompactOrganisationDC org = null;

            Calculations calc = null;
	        var cb2scOids = new List<long>();

            foreach (CompactSupportConceptDC scdc in multiSupportConceptControl.SelectedSupportConcepts)
            {
				
                if (scdc.CostBearerList.Count > 0)
                {
					cb2scOids.Add(scdc.CostBearerList[0].CostBearer2SupportConceptOid);

                    if (org == null)
                    {
                        org = scdc.CostBearerList[0].Organisation;
                        if (org != null)
                        {
                            minuteInterval = org.ActualMinuteIntervall;
                        }
                    }
                    else
                    {
                        if (scdc.CostBearerList[0].Organisation == null || !org.Equals(scdc.CostBearerList[0].Organisation))
                            roundDuration = false;
                    }
                }
            }

			decimal duration = _ServiceRecordVM.Duration.Value;
            decimal lRoundedDuration = duration;

            int personCount = multiSupportConceptControl.SelectedSupportConcepts.Count;
            int employeeCount = multiEmployeeControl.SelectedEmployees.Count;

            decimal groupDuration = 0;
            decimal roundedDuration = 0;


			GroupDurationDC gd = ServiceRecordListVM.CalculateGroupDuration(personCount, employeeCount, lRoundedDuration, cb2scOids);
	        if (gd != null)
	        {
				groupDuration = gd.TotalDuration;
				roundedDuration = gd.SingleDuration;
	        }
	        else
	        {
		        if (personCount > 2 && (BeWoApp.Tenant == "9893557471") || (BeWoApp.Tenant == "2918696314"))
			        //Caritas Frankfurt
		        {
			        decimal groupRoundedDuration = lRoundedDuration;

			        roundedDuration = ((groupRoundedDuration*employeeCount)/personCount) + 10;
			        groupDuration = groupRoundedDuration;
		        }
		        else if (personCount > 1 && BeWoApp.Tenant == "5653806613") //Feid&Kollegen
		        {
			        decimal groupRoundedDuration = lRoundedDuration;

			        roundedDuration = ((groupRoundedDuration*employeeCount)/personCount);
			        groupDuration = groupRoundedDuration;
		        }
		        else
		        {
			        if (minuteInterval > 0 && roundDuration)
				        lRoundedDuration = duration%minuteInterval != 0
					        ? duration + (minuteInterval - (duration%minuteInterval))
					        : duration;

			        groupDuration = lRoundedDuration;
			        roundedDuration = Math.Round(groupDuration/multiSupportConceptControl.SelectedSupportConcepts.Count, 0,
				        MidpointRounding.AwayFromZero);

			        if (BeWoApp.Tenant == "0216265667") //Lebenshilfe Hannover
			        {
				        roundedDuration += 10;
			        }
		        }
	        }

	        _ServiceRecordVM.RoundedDuration = roundedDuration;
			_ServiceRecordVM.GroupRoundedDuration = groupDuration;


            _Group.Notice  = dc.Notice;
            _Group.Notice2 = dc.Notice2;
            _Group.Notice3 = dc.Notice3;
            _Group.Notice4 = dc.Notice4;
            _Group.Notice5 = dc.Notice5;
            _Group.RoundedDuration = groupDuration;
            _Group.StartDate = dc.Start;
            _Group.EndDate = dc.End;
            _Group.EmployeeCount = multiEmployeeControl.SelectedEmployees.Count;
            _Group.CustomerCount = multiSupportConceptControl.SelectedSupportConcepts.Count;
            
            foreach (ServiceRecordDC item in _Group.ServiceRecordList)
            {
                item.Notice = dc.Notice;
                item.Notice2 = dc.Notice2;
                item.Notice3 = dc.Notice3;
                item.Notice4 = dc.Notice4;
                item.Notice5 = dc.Notice5;
                item.End = dc.End;
                item.Start = dc.Start;
                item.RoundedDuration = roundedDuration;
	            item.DistanceInMeter = dc.DistanceInMeter;
                item.ServiceDescription = dc.ServiceDescription;

                item.ServiceDescription = item.ServiceDescription ?? dc.ServiceDescription;

                item.GroupEmployeeCount = _Group.EmployeeCount;
                item.GroupPersonCount = _Group.CustomerCount;
                item.GroupOid = dc.GroupOid;
                item.GroupRoundedDuration = groupDuration;

                CompactOrganisationDC i1 = item.CostBearer;
                long? i2 = item.CostBearer.CostBearerOid;
                CompactSupportConceptDC i3 = item.SupportConcept;

                if (item.SupportConcept != null && item.SupportConcept.CostBearerList != null && item.SupportConcept.CostBearerList.Count > 0)
                {
                    CompactCostBearerDC i4 = item.SupportConcept.CostBearerList[0];

                    long i5 = i4.CostBearerOid;
                }
                if (item.CostBearer != null && item.CostBearer.CostBearerOid == null && item.SupportConcept != null && item.SupportConcept.CostBearerList.Count > 0)
                    item.CostBearer.CostBearerOid = item.SupportConcept.CostBearerList[0].CostBearerOid;
            }

            

            ServiceFacade.DoOperationsServiceAsync(s => s.UpdateServiceRecordGroup(_Group), UpdateViewModel);
        }

        private void InitSelectionList()
        {
            if (_Group == null) 
                return;

            if (_Group.ServiceRecordList == null) 
                return;

            foreach (ServiceRecordDC item in _Group.ServiceRecordList)
            {
                if (!multiEmployeeControl.SelectedEmployees.Contains(item.Employee))
                    multiEmployeeControl.SelectedEmployees.Add(item.Employee);

                if (!multiSupportConceptControl.SelectedSupportConcepts.Contains(item.SupportConcept))
                    multiSupportConceptControl.SelectedSupportConcepts.Add(item.SupportConcept);
            }
        }

	    private bool IsSupportConceptOrEmployeeChanged()
	    {
		    var newEmployees = new List<CompactEmployeeDC>();
		    var newSupportConcepts = new List<CompactSupportConceptDC>();

		    var oldSCs = new Dictionary<long, CompactSupportConceptDC>();
		    var oldEmps = new Dictionary<long, CompactEmployeeDC>();
		    var oldCb2Scs = new Dictionary<long, bool>();

		    foreach (var item in _Group.ServiceRecordList)
		    {
			    if (!oldEmps.ContainsKey(item.Employee.EmployeeOid))
				    oldEmps.Add(item.Employee.EmployeeOid, item.Employee);

			    if (!oldSCs.ContainsKey(item.SupportConcept.SupportConceptOid))
				    oldSCs.Add(item.SupportConcept.SupportConceptOid, item.SupportConcept);
			    if (item.CostBearer2SupportConceptOid.HasValue)
			    {
				    if (!oldCb2Scs.ContainsKey(item.CostBearer2SupportConceptOid.Value))
					    oldCb2Scs.Add(item.CostBearer2SupportConceptOid.Value, true);
			    }
		    }

		    foreach (CompactEmployeeDC emp in multiEmployeeControl.SelectedEmployees)
		    {
			    if (!oldEmps.ContainsKey(emp.EmployeeOid))
				    return true;
			    else
				    oldEmps.Remove(emp.EmployeeOid);
		    }

		    foreach (CompactSupportConceptDC sc in multiSupportConceptControl.SelectedSupportConcepts)
		    {
			    if (!oldSCs.ContainsKey(sc.SupportConceptOid))
				    return true;
			    else
				    oldSCs.Remove(sc.SupportConceptOid);

			    if (sc.CostBearerList != null && sc.CostBearerList.Count > 0)
			    {
				    if (!oldCb2Scs.ContainsKey(sc.CostBearerList[0].CostBearer2SupportConceptOid))
					    return true;
				    else
					    oldCb2Scs.Remove(sc.CostBearerList[0].CostBearer2SupportConceptOid);
			    }
		    }
		    return oldSCs.Count > 0 || oldEmps.Count > 0 || oldCb2Scs.Count > 0;
	    }

	    private void ServiceRecordGroupEditView_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        private void UpdateServiceRecordGroup()
        {
            var dcsToKeep = new Dictionary<string, ServiceRecordDC>();
            var dcsToChange = new List<ServiceRecordDC>();
            var oldSCs = new Dictionary<long, CompactSupportConceptDC>();
            var oldEmps = new Dictionary<long, CompactEmployeeDC>();
            var newKeys = new Dictionary<string, string>();

            foreach (CompactSupportConceptDC sc in multiSupportConceptControl.SelectedSupportConcepts)
            {
                foreach (var emp in multiEmployeeControl.SelectedEmployees)
                {
                    var key = emp.EmployeeOid + "_" + sc.SupportConceptOid;
	                if (sc.CostBearerList != null && sc.CostBearerList.Count > 0)
		                key += "_" + sc.CostBearerList[0].CostBearer2SupportConceptOid;

                    newKeys.Add(key, key);
                }
            }

            foreach (var item in _Group.ServiceRecordList)
            {
                var key = item.Employee.EmployeeOid + "_" + item.SupportConcept.SupportConceptOid;
	            if (item.CostBearer2SupportConceptOid.HasValue)
		            key += "_" + item.CostBearer2SupportConceptOid.Value;

                if (newKeys.ContainsKey(key))
                {
                    dcsToKeep.Add(key, item);
                    newKeys.Remove(key);
                }
                else
                {
                    dcsToChange.Add(item);
                }

                if (!oldEmps.ContainsKey(item.Employee.EmployeeOid))
                    oldEmps.Add(item.Employee.EmployeeOid, item.Employee);

                if (!oldSCs.ContainsKey(item.SupportConcept.SupportConceptOid))
                    oldSCs.Add(item.SupportConcept.SupportConceptOid, item.SupportConcept);
            }

            
            if (newKeys.Count != 0 || dcsToChange.Count != 0)
            {
                if (newKeys.Count > 0)
                {
                    foreach (var sc in multiSupportConceptControl.SelectedSupportConcepts)
                    {
                        foreach (var emp in multiEmployeeControl.SelectedEmployees)
                        {
                            var key = emp.EmployeeOid + "_" + sc.SupportConceptOid;
							if (sc.CostBearerList != null && sc.CostBearerList.Count > 0)
								key += "_" + sc.CostBearerList[0].CostBearer2SupportConceptOid;

                            if (!newKeys.ContainsKey(key)) 
                                continue;

                            ServiceRecordDC newServiceRecord;
                            if (dcsToChange.Count > 0)
                            {
                                newServiceRecord = dcsToChange[0];
                                dcsToChange.Remove(newServiceRecord);
                            }
                            else
                            {
								newServiceRecord = _ServiceRecordVM.Clone().CommitToDataContract();
                                _Group.ServiceRecordList.Add(newServiceRecord);
                            }

                            newServiceRecord.Employee = emp;
                            newServiceRecord.SupportConcept = sc;
                            newServiceRecord.CostBearer = sc.CostBearerList[0].Organisation;
                            newServiceRecord.Customer = sc.Customer;
                            newServiceRecord.CostBearer2SupportConceptOid = sc.CostBearerList[0].CostBearer2SupportConceptOid;
                        }
                    }
                }

                foreach (var item in dcsToChange)
                    _Group.ServiceRecordList.Remove(item);
            }
        }

        private void UpdateViewModel(ServiceRecordGroupDC newGroupDC)
        {
            Dispatcher.BeginInvoke(
                DispatcherPriority.Normal, 
                (Action)delegate
                    {
                        var deleteList = ViewModel.VMList.Where(item => item.GroupOid != null &&
																		item.GroupOid.Value == _ServiceRecordVM.GroupOid.Value).ToList();

                        foreach (var item in deleteList)
                            ViewModel.VMList.Remove(item);

                        var customerOids = new Dictionary<long, long>();
                        foreach (var item in newGroupDC.ServiceRecordList)
                        {
                            if (customerOids.ContainsKey(item.Customer.CustomerOid)) 
                                continue;

                            // ###AddServiceRecord
                            var newVM = ViewModel.CreateNewVM(item);
                            ViewModel.VMList.Add(newVM);
                            customerOids.Add(item.Customer.CustomerOid, 1);

                            // if (item.GroupOid != null && item.GroupOid.Value == _OriginalVM.GroupOid.Value)
                            // {
                            // item.Notice = _OriginalVM.Notice;
                            // item.StartTime = _OriginalVM.StartTime;
                            // item.EndTime = _OriginalVM.EndTime;
                            // item.Date = _OriginalVM.Date;
                            // item.Duration = _OriginalVM.Duration;
                            // item.RoundedDuration = _OriginalVM.RoundedDuration;

                            // item.Category = _OriginalVM.Category;
                            // item.ServiceDescription = _OriginalVM.ServiceDescription;
                            // item.GroupEmployeeCount = _OriginalVM.GroupEmployeeCount;
                            // item.GroupPersonCount = _OriginalVM.GroupPersonCount;
                            // item.GroupRoundedDuration = _OriginalVM.GroupRoundedDuration;

                            // }
                        }

                        ViewModel.RefreshServiceRecordsForSelectedTreeNode();
                    });
        }

        private void ConfigureDocTypes()
        {
            //Tabs und Tabelle
            int i = ViewModel.AllDocTypes.Count;

            if (i == 0)
            {
                TabItem1_Notice.Header = "Dokumentation";
                TabItem2_Notice.Visibility = Visibility.Collapsed;
                TabItem3_Notice.Visibility = Visibility.Collapsed;
                TabItem4_Notice.Visibility = Visibility.Collapsed;
                TabItem5_Notice.Visibility = Visibility.Collapsed;

            }
            else if (i == 1)
            {
                TabItem1_Notice.Header = ViewModel.AllDocTypes[0].ToString();

                TabItem2_Notice.Visibility = Visibility.Collapsed;
                TabItem3_Notice.Visibility = Visibility.Collapsed;
                TabItem4_Notice.Visibility = Visibility.Collapsed;
                TabItem5_Notice.Visibility = Visibility.Collapsed;

            }
            else if (i == 2)
            {
                TabItem1_Notice.Header = ViewModel.AllDocTypes[0].ToString();
                TabItem2_Notice.Header = ViewModel.AllDocTypes[1].ToString();

                TabItem3_Notice.Visibility = Visibility.Collapsed;
                TabItem4_Notice.Visibility = Visibility.Collapsed;
                TabItem5_Notice.Visibility = Visibility.Collapsed;

            }
            else if (i == 3)
            {
                TabItem1_Notice.Header = ViewModel.AllDocTypes[0].ToString();
                TabItem2_Notice.Header = ViewModel.AllDocTypes[1].ToString();
                TabItem3_Notice.Header = ViewModel.AllDocTypes[2].ToString();

                TabItem4_Notice.Visibility = Visibility.Collapsed;
                TabItem5_Notice.Visibility = Visibility.Collapsed;

            }
            else if (i == 4)
            {
                TabItem1_Notice.Header = ViewModel.AllDocTypes[0].ToString();
                TabItem2_Notice.Header = ViewModel.AllDocTypes[1].ToString();
                TabItem3_Notice.Header = ViewModel.AllDocTypes[2].ToString();
                TabItem4_Notice.Header = ViewModel.AllDocTypes[3].ToString();

                TabItem5_Notice.Visibility = Visibility.Collapsed;

            }
            else if (i == 5)
            {
                TabItem1_Notice.Header = ViewModel.AllDocTypes[0].ToString();
                TabItem2_Notice.Header = ViewModel.AllDocTypes[1].ToString();
                TabItem3_Notice.Header = ViewModel.AllDocTypes[2].ToString();
                TabItem4_Notice.Header = ViewModel.AllDocTypes[3].ToString();
                TabItem5_Notice.Header = ViewModel.AllDocTypes[4].ToString();
            }

        }
    }
}