using System;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using BeWo.Core;
using BeWo.Core.Service;
using BeWo.ServiceProxy;
using BeWo.Validation;
using BeWo.ViewModel;

using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using DevExpress.Xpf.Grid;

using CheckBox = System.Windows.Controls.CheckBox;

namespace BeWo.View.Detail
{
    public partial class CustomerView2 : BeWoView
    {
        private PersonView _PersonModalPopUp;

        private OrganisationView _OrganisationModalPopUp;

        private CustomerVM _ViewModel;

        private GridControl grid_AbsenceTimes;
        private GridControl grid_EmployeeRelation;
        private GridControl grid_TeamRelation;
        private GridControl grid_Persons;
        private GridControl grid_Organisations;
        private GridControl grid_costBearers;

        private StringBuilder _LogText;

        public CustomerView2(CustomerVM pCustomerVM)
        {
            InitializeComponent();

            if (ShouldLog)
            {
                _LogText = new StringBuilder();
                tabitem_log.Visibility = Visibility.Visible;
            }
            else
            {
                tabitem_log.Visibility = Visibility.Collapsed;
            }

            ViewModel = pCustomerVM;          

            if (pCustomerVM.VarFields == null || pCustomerVM.VarFields.VMList.Count == 0)
                tabitem_varFields.Visibility = Visibility.Collapsed;
            if (!BeWoApp.AppSettings.ShowLargeCustomerNotice)
                tabitem_notice.Visibility = Visibility.Collapsed;
            // HACK: Force the devexpress grid to end editing when the mouse is over savebutton
            // by setting the focus to another element. 
            MouseMove += (s, e) =>
                {
                    if ((grid_AbsenceTimes == null || !grid_AbsenceTimes.IsVisible) && 
                        (grid_EmployeeRelation == null || !grid_EmployeeRelation.IsVisible) &&
                        (grid_TeamRelation == null || !grid_TeamRelation.IsVisible) &&
                        (grid_costBearers == null || !grid_costBearers.IsVisible) && 
                        (grid_Persons == null || !grid_Persons.IsVisible) &&
                        (grid_Organisations == null || !grid_Organisations.IsVisible))
                    {
                        return;
                    }

                    Point p = e.GetPosition(btnSave);

                    if (p.X >= 0 && p.X < btnSave.ActualWidth && p.Y >= 0 && p.Y < btnSave.ActualHeight)
                    {
                        var i = tabroot.Focus();
                    }
                };

            InitCustomerCareTypeList();

            panelDebitor.Visibility = Visibility.Visible;

            txtDebitorNumber.Visibility = lblDebitorNumber.Visibility;

            if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.Customer_AllowArchiving))
            {
                lblArchiviert.Visibility = Visibility.Hidden;
                chkArchiviert.Visibility = Visibility.Hidden;
            }

			if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.DocumentsAllowViewAll) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.DokumenteKlienten))
			{
				tabitem_documents.Visibility = Visibility.Collapsed;
			}

            Log("Jugendhilfeklient geöffnet");
        }

        private void Log(string log)
        {
            if (!ShouldLog) 
                return;

            if (_LogText == null)
                _LogText = new StringBuilder();
            if (_LogText.Length > 0)
                _LogText.Append("\n");
            _LogText.Append(log);
        }

        public override bool IsDirty
        {
            get { return ViewModel != null ? ViewModel.IsDirty : false; }
        }

        public override string Title
        {
            get { return "Klienten"; }
        }

        internal override DependencyObject ValidationOnSaveRootElement
        {
            get
            {
                return grid_details;
            }
        }

        private CustomerVM ViewModel
        {
            get { return _ViewModel; }

            set
            {
                _ViewModel = value;
                root.DataContext = value;

                Log(String.Format("ViewModel gesetzt. DataContext={0}", root.DataContext));

                if (_ViewModel != null && ShouldLog)
                    _ViewModel.EnableLogging(true, _LogText);

                if (ViewModel.Jugendamt != null)
                {
                    popupedit_OrganisationSearch.Text = ViewModel.Jugendamt.ToString();
                    personsearchview.OrganisationRelOid = ViewModel.Jugendamt.OrganisationOid;
                    personsearchview.UpdateFilteredList();
                }

                if (ViewModel.Ansprechpartner != null)
                    popupedit_PersonSearch.Text = ViewModel.Ansprechpartner.ToString();
            }
        }

        public override void ModalPopUpCloseInvoked()
        {
            MainControl.CloseCurrentPopUp();
        }

        public override void ModalPopUpSaveInvoked()
        {
            // TODO nicht  schön, umbauen wenn an weiteren Stellen popup hierachien nötig werden
            if (_PersonModalPopUp != null)
            {
                if (_PersonModalPopUp._OrganisationModalPopUp != null)
                    _PersonModalPopUp._OrganisationModalPopUp.SaveData();
                else
                    _PersonModalPopUp.SaveData();
            }
            else if (_OrganisationModalPopUp != null)
            {
                _OrganisationModalPopUp.SaveData();
            }
        }

        protected override UserRightType[] GetSaveDemands()
        {
            return ViewModel.IsNew ? new[] { UserRightType.CreateAll, UserRightType.CustomerView_Create } : new[] { UserRightType.EditAll, UserRightType.CustomerView_Edit };
        }

        protected override void Save()
        {
            CustomerDC lDataContract = ViewModel.CommitToDataContract();
            try
            {
                if (ViewModel.IsNew)
                {
                    ServiceFacade.DoCustomerServiceAsync(s => s.InsertNewCustomer(lDataContract), ReloadViewModel);
                }
                else
                {
                    ServiceFacade.DoCustomerServiceAsync(s => s.UpdateCustomer(lDataContract), ReloadViewModel);
                }

                Cache.GetInstance().ClearSupportConceptTree();
				Cache.GetInstance().ClearCustomers();
                BeWoApp.MainControl.ResetView(UIContext.Customer);
            }
            catch (FaultException<BeWoFault>)
            {
                MessageBox.Show("Dieser Datensatz wurde in der Zwischenzeit von einem anderen Benutzer geändert. Klicken Sie Ok um den Datansatz erneut zu laden. Ihre Änderungen gehen dabei leider verloren.");
                this.ReloadViewModel(lDataContract.CustomerOid.Value);
            }
        }

        private void Button_deleteCostBearerClick(object sender, RoutedEventArgs e)
        {
            ViewModel.CostBearers.VMList.Remove(grid_costBearers.GetCurrentValue<CustomerCostBearerRealtionVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_costBearers);
        }

        private void EmployeeSearchView_ItemSelected_1(object sender, EventArgs<CompactEmployeeDC> e)
        {
            popup_employee.IsOpen = false;
            ViewModel.EmployeeRelations.NewVM.Employee = e.Data;
            //this.popupedit_employeeRelations.Focus();
        }

        private void TeamSearchView_ItemSelected_1(object sender, EventArgs<CompactTeamDC> e)
        {
            popup_team.IsOpen = false;
            ViewModel.TeamRelations.NewVM.Team = e.Data;
            //popupedit_teamRelations.Focus();
        }

        private void InitCustomerCareTypeList()
        {
            foreach (ValueListEntryDC dc in ViewModel.PossibleCustomerCareTypes)
            {
                CheckBox chkBox = new CheckBox();
                chkBox.IsChecked = ViewModel.CustomerCareTypes.Contains(dc);
                chkBox.Content = dc;
                chkBox.Checked += (s, e) =>
                    {
                        CheckBox cb = (CheckBox)s;
                        ViewModel.CustomerCareTypes.Add((ValueListEntryDC)cb.Content);
                    };
                chkBox.Unchecked += (s, e) =>
                    {
                        CheckBox cb = (CheckBox)s;
                        ViewModel.CustomerCareTypes.Remove((ValueListEntryDC)cb.Content);
                    };
                //this.customerCareTypeList.Items.Add(chkBox);
            }
        }

        private void ReloadViewModel(long pCustomerOID)
        {
            // reload to update version informations and oid
            VMFactory.CreateCustomerVMAsync(pCustomerOID, cb => this.Dispatch(delegate { ViewModel = cb; }));
        }

        private void TabItemAbsenceTimes_Selected(object sender, RoutedEventArgs e)
        {
            if (grid_AbsenceTimes != null) 
                return;

            grid_AbsenceTimes = root.Resources["datagrid_absences"] as GridControl;

            //var col = this.grid_AbsenceTimes.Columns["End"];
            //DateEditSettings des = col.EditSettings as DateEditSettings;
            //des.DisplayTextConverter = new DateNullValueToEmptyStringConverter();

            GroupBoxAbsenceTimes.Content = this.grid_AbsenceTimes;

            //if (ViewModel.AbsenceTimes != null)
            //    grid_AbsenceTimes.Columns["Reason"].EditSettings = new ComboBoxEditSettings { ItemsSource = ViewModel.AbsenceTimes.PossibleReasons };
        }

        private void TabItemCostBearer_Selected(object sender, RoutedEventArgs e)
        {
            if (this.grid_costBearers == null)
            {
                this.grid_costBearers = this.root.Resources["grid_costBearer"] as GridControl;
                this.GroupBoxCostBearerGrid.Content = this.grid_costBearers;
            }
        }

        private void UserControl_GotFocus(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource.Equals(this))
            {
                this.textbox_first.Focus();
            }
        }

        private void button_addAbsence_Click(object sender, RoutedEventArgs e)
        {
            if (ValidationTrigger.Validate(groupbox_newAbsenceTime))
                ViewModel.AbsenceTimes.AddNewVMToList();
        }

        private void button_addCostBearer_Click(object sender, RoutedEventArgs e)
        {
            if (ValidationTrigger.Validate(groupBox_newCostBearer))
                ViewModel.CostBearers.AddNewVMToList();
        }

        private void button_environmentPersonDeleteClick(object sender, RoutedEventArgs e)
        {
            ViewModel.EnvironmentPersons.VMList.Remove(grid_Persons.GetCurrentValue<CustomerPersonRelationVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_Persons);
        }

        private void button_environmentOrganisationDeleteClick(object sender, RoutedEventArgs e)
        {
            ViewModel.EnvironmentOrganisations.VMList.Remove(grid_Organisations.GetCurrentValue<CustomerOrganisationRelationVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_Organisations);
        }

        private void button_removeAbsence_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.AbsenceTimes.VMList.Remove(grid_AbsenceTimes.GetCurrentValue<AbsenceTimeVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_AbsenceTimes);
        }

        private void button_removeEmployeeRelation_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.EmployeeRelations.VMList.Remove(grid_EmployeeRelation.GetCurrentValue<CustomerEmployeeRelationVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_EmployeeRelation);
        }

        private void button_removeTeamRelation_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.TeamRelations.VMList.Remove(grid_TeamRelation.GetCurrentValue<CustomerTeamRelationVM>());
            BeWoWpfUtils.RefreshDXGrid(grid_TeamRelation);
        }

        private void costbearersearchview_ItemSelected(object sender, EventArgs<CompactOrganisationDC> e)
        {
            popup_costBearer.IsOpen = false;
            ViewModel.CostBearers.NewVM.CostBearer = e.Data;
            popup_costBearer.Focus();
        }

        private void popupedit_OrganisationSearch_PopUpClick(object sender, RoutedEventArgs e)
        {
            jugendamtsearchview.ItemSelected += organisationsearchview_OrganisationSelected;
            popup_organisation.IsOpen = true;
        }

        private void organisationsearchview_OrganisationSelected(object sender, EventArgs<CompactOrganisationDC> e)
        {
            popup_organisation.IsOpen = false;
            jugendamtsearchview.ItemSelected -= organisationsearchview_OrganisationSelected;
            ViewModel.Jugendamt = e.Data;

            if (ViewModel.Ansprechpartner != null)
            {
                bool ansprechpartnerInJugendamt = false;
                foreach (var relation in ViewModel.Ansprechpartner.OrganisationRelations.Where(relation => relation.Organisation.OrganisationOid == ViewModel.Jugendamt.OrganisationOid))
                    ansprechpartnerInJugendamt = true;

                if (!ansprechpartnerInJugendamt)
                {
                    ViewModel.Ansprechpartner = null;
                    popupedit_PersonSearch.Text = string.Empty;
                }
            }
            
            personsearchview.OrganisationRelOid = ViewModel.Jugendamt.OrganisationOid;
            personsearchview.UpdateFilteredList();
            popupedit_OrganisationSearch.Text = e.Data.ToString();
            popupedit_OrganisationSearch.Focus();
        }

        private void popupedit_PersonSearch_PopUpClick(object sender, RoutedEventArgs e)
        {
            personsearchview.ItemSelected += personsearchview_PersonSelected;
            popup_person.IsOpen = true;
        }

        private void personsearchview_PersonSelected(object sender, EventArgs<CompactPersonDC> e)
        {
            popup_person.IsOpen = false;
            personsearchview.ItemSelected -= personsearchview_PersonSelected;
            ViewModel.Ansprechpartner = e.Data;
            popupedit_PersonSearch.Text = e.Data.ToString();
            popupedit_PersonSearch.Focus();
        }

        private void popupedit_costBearer_PopUpClick(object sender, RoutedEventArgs e)
        {
            popup_costBearer.IsOpen = true;
        }

        private void tabitem_documents_Selected(object sender, RoutedEventArgs e)
        {
            if (ViewModel.IsNew)
            {
                // TODO
                MessageBox.Show("Bevor zu einem Datensatz Dokumente hinterlegt werden können, muss dieser gespeichert werden.", "Erst speichern bitte", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            if (tabitem_documents.Content == null)
            {
                tabitem_documents.Content = new BeWoFileView(TableID.Customer, ViewModel.DataContract.CustomerOid.Value);
            }
        }

        private void tabitem_log_Selected(object sender, RoutedEventArgs e)
        {
            if (!ShouldLog)
                return;

            TextBlock txt = tabitem_log.Content as TextBlock;

            if (txt == null)
            {
                txt = new TextBlock();
                tabitem_log.Content = txt;
            }
            if (_LogText != null)
                txt.Text = _LogText.ToString();
        }

        public bool ShouldLog
        {
            get { return BeWoApp.Tenant == "1549622397" && BeWoApp.UserName.ToLower() == "h.krause"; }
            //get { return BeWoApp.Tenant == "demo" && BeWoApp.UserName == "demo"; }
        }
    }
}