using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using BS.Shared;
using BeWo.Controls;
using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;

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

namespace BeWo.View.Detail.Accounting
{
    public partial class ServiceInvoiceView : BeWoView
    {
        private readonly ServiceInvoiceCreatePopUpView _CreatePopUpView;

        private readonly ServiceInvoiceItemEditView _EditView;

        private ServiceInvoiceViewVM _Viewmodel;

        public ServiceInvoiceView()
        {
            var lastMonth = DateTime.Now.AddMonths(-1);
            this.InitializeComponent();

            this.ViewModel = new ServiceInvoiceViewVM
                             {
                                 InvoicePeriodStart = lastMonth.AddDays(-lastMonth.Day + 1),
                                 InvoicePeriodEnd = DateTime.Now.AddDays(-DateTime.Now.Day),
                                 IsAllSupportConcepts = false,
                                 IsUseApprovalPeriod = false,
                                 ServiceInvoiceListVM = new ServiceInvoiceListVM(new List<ServiceInvoiceDC>())
                             };

            

            this._EditView = new ServiceInvoiceItemEditView();
            this._EditView.EditingFinished += (s, e) =>
                                              {
                                                  this.RefreshViewModel();
                                                  this.MainControl.CloseCurrentPopUp();
                                              };

            this._CreatePopUpView = new ServiceInvoiceCreatePopUpView();
            this._CreatePopUpView.Closed += (s, e) =>
                                            {
                                                this.MainControl.CloseCurrentPopUp();
                                                ServiceFacade.DoAccountingServiceAsync(svc => svc.InsertNewServiceInvoices(e.Data),
                                                                                       this.RefreshViewModel);
                                            };
        }

        internal ServiceInvoiceViewVM ViewModel
        {
            get
            {
                return this._Viewmodel;
            }

            set
            {
                this.DataContext = value;
                this._Viewmodel = value;
                value.PropertyChanged += (s, e) =>
                                         {
                                             if (!e.PropertyName.Equals(ServiceInvoiceViewVM.PropertyName_IsSelectionValid)&&
                                                 !e.PropertyName.Equals(ServiceInvoiceViewVM.PropertyName_ServiceInvoiceListVM))
                                             {
                                                 this.RefreshViewModel();
                                             }
                                         };
            }
        }

        private void IsPrintingListChanged()
        {
            SetCeSelectAllState();
            List<long> isPrintingIds = this.ViewModel.GetIsPrintingIds();

            if (isPrintingIds.Count == 0)
            {
                this.tb_printAll.Visibility = Visibility.Hidden;
            }
            else
            {
                this.tb_printAll.Visibility = Visibility.Visible;
                string url = BeWoApp.SiteOfOrigin + "/ReportView.aspx?dcids=" + string.Join(";", isPrintingIds.Select(i => i.ToString()).ToArray())
                             + "&type=" + Utils.EnumName(ReportTypes.ServiceInvoice);

                string token = string.Empty;
                ServiceFacade.DoDownloadServiceSync(s => token = s.CreateTemporaryToken(url, false));

                url += "&token=" + token;
                url = BeWoWpfUtils.GetHTMLEncodedURL(url);

                // Workaround Hyperlink mit neuem ersetzen, Navigate Uri lässt auf dem alten nicht ändern...
                this.tb_printAll.Inlines.Clear();
                var lNewLink = new Hyperlink(new Run("markierte Rechnungen drucken"))
                               {
                                   NavigateUri = new Uri(url),
                                   TargetName = "_newWindow",
                                   Foreground = Brushes.Blue
                               };
                lNewLink.Click += clickTest;
                this.tb_printAll.Inlines.Add(lNewLink);
            }
        }

        private void clickTest(object sender, RoutedEventArgs rea)
        {
            var hl = (Hyperlink)sender;
            List<long> isPrintingIds = ViewModel.GetIsPrintingIds();
            var url = BeWoApp.SiteOfOrigin + "/ReportView.aspx?dcids=" + string.Join(";", isPrintingIds.Select(i => i.ToString()).ToArray()) + "&type=" + Utils.EnumName(ReportTypes.ServiceInvoice);
            var token = string.Empty;

            ServiceFacade.DoDownloadServiceSync(s => token = s.CreateTemporaryToken(url, false));

            url += "&token=" + token;
            url = BeWoWpfUtils.GetHTMLEncodedURL(url);

            BeWoUtils.NavigateToReportUri(url, null);
            //System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(url));
        }

        private void RefreshViewModel()
        {
            if (!this.ViewModel.IsSelectionValid)
            {
                this.ViewModel.ServiceInvoiceListVM = new ServiceInvoiceListVM(new List<ServiceInvoiceDC>());
                if (this.grid_printselect != null)
                {
                    this.grid_printselect.Visibility = Visibility.Hidden;
                }
                this.ce_selectAll.IsChecked = false;
                return;
            }

            List<long> isPrintingIds = this.ViewModel.GetIsPrintingIds();

            ServiceFacade.DoAccountingServiceAsync(s => s.GetServiceInvoices(this.ViewModel.SelectedCostBearer.CostBearerOid.Value,
                                                                             this.ViewModel.GetSupportConceptOid(),
                                                                             this.ViewModel.GetPeriodSpan()),
                                                   cb => this.Dispatch(() =>
                                                                       {
                                                                          
                                                                           this.ViewModel.ServiceInvoiceListVM = new ServiceInvoiceListVM(cb);
                                                                           
                                                                           foreach (var iVm in this.ViewModel.ServiceInvoiceListVM.VMList)
                                                                           {
                                                                               iVm.IsPrinting = isPrintingIds.Contains(iVm.DataContract.ServiceInvoiceOid.Value);
                                                                           }

                                                                           this.SetCeSelectAllState();

                                                                           this.ViewModel.ServiceInvoiceListVM.VMList.ListChanged += this.ServiceInvoiceList_ListChanged;

                                                                           this.grid_printselect.Visibility = this.ViewModel.ServiceInvoiceListVM.VMList.Count > 0
                                                                                                                  ? Visibility.Visible
                                                                                                                  : Visibility.Hidden;
                                                                       }));
        }

        private void ServiceInvoiceList_ListChanged(object sender, ListChangedEventArgs e)
        {
            if (e.ListChangedType == ListChangedType.ItemChanged
                && e.PropertyDescriptor.Name.Equals(ServiceInvoiceVM.PropertyName_IsPrinting))
            {
                this.IsPrintingListChanged();
            }
        }

        private void SetCeSelectAllState()
        {
            this.ce_selectAll.Checked -= this.ce_selectAll_Checked;
            this.ce_selectAll.Unchecked -= this.ce_selectAll_Unchecked;

            this.ce_selectAll.IsChecked = this.ViewModel.ServiceInvoiceListVM.VMList.All(i => i.IsPrinting);

            this.ce_selectAll.Checked += this.ce_selectAll_Checked;
            this.ce_selectAll.Unchecked += this.ce_selectAll_Unchecked;
        }

        private void SupportConceptSearchView_ItemSelected(object sender, EventArgs<CompactSupportConceptDC> e)
        {
            this.popup_supportConcept.IsOpen = false;
            this.ViewModel.SelectedSupportConcept = e.Data;
        }

        private void bt_selectAllDate_Click(object sender, RoutedEventArgs e)
        {
            this.ce_selectAll.IsChecked = true;
            foreach (var i in this.ViewModel.ServiceInvoiceListVM.VMList)
            {
                i.IsPrinting = i.InvoiceBase.InvoiceDate.Value.Date.Equals(this.dt_selectAll.DateTime.Date);
            }

            this.SetCeSelectAllState();
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("Sind Sie sicher, dass Sie den gewählten Eintrag löschen möchten?",
                                "Spitzabrechnung löschen",
                                MessageBoxButton.YesNo,
                                MessageBoxImage.Warning) == MessageBoxResult.Yes)
            {
                var vm = BeWoWpfUtils.GetTag<ServiceInvoiceVM>(sender);

                ServiceFacade.DoAccountingServiceAsync(s => s.DeactivateServiceInvoices(new[]
                                                                                        {
                                                                                            vm.DataContract
                                                                                        }.ToList()),
                                                       () => this.Dispatch(() => this.ViewModel.ServiceInvoiceListVM.VMList.Remove(vm)));
            }
        }

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            this._EditView.ViewModel = BeWoWpfUtils.GetTag<ServiceInvoiceVM>(sender);
            this.MainControl.ShowControlAsModalPopUp(this._EditView);
        }

        private void button_createInvoice_Click(object sender, RoutedEventArgs e)
        {
            ServiceFacade.DoAccountingServiceAsync(s => s.GenerateInitialServiceInvoices(this.ViewModel.SelectedCostBearer.CostBearerOid.Value,
                                                                                         this.ViewModel.GetSupportConceptOid(),
                                                                                         this.ViewModel.GetPeriodSpan()),
                                                   r => this.Dispatch(() =>
                                                                      {
                                                                          this._CreatePopUpView.ServiceInvoiceDcs = r;
                                                                          this.MainControl.ShowControlAsModalPopUp(this._CreatePopUpView);
                                                                      }));
        }

        private void ce_selectAll_Checked(object sender, RoutedEventArgs e)
        {
            foreach (var i in this.ViewModel.ServiceInvoiceListVM.VMList)
            {
                i.IsPrinting = true;
            }
        }

        private void ce_selectAll_Unchecked(object sender, RoutedEventArgs e)
        {
            foreach (var i in this.ViewModel.ServiceInvoiceListVM.VMList)
            {
                i.IsPrinting = false;
            }
        }

        private void organisationSearchView_ItemSelected(object sender, EventArgs<CompactOrganisationDC> e)
        {
            this.ViewModel.SelectedCostBearer = e.Data;
            this.ViewModel.SelectedSupportConcept = null;
            this.popup_costBearer.IsOpen = false;
        }

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

        private void popupedit_supportConcept_PopUpClick(object sender, RoutedEventArgs e)
        {
            this.popup_supportConcept.IsOpen = true;
        }

        private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
        {
	        BeWoUtils.NavigateToReportUri(((Hyperlink) sender).NavigateUri.ToString(), null);
        }

        private void Popupedit_CostBeaerer_OnPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (!BeWoUtils.CheckPopupEditClickableSpace((PopUpEdit)sender, e) || ViewModel.SelectedCostBearer == null || !BeWoApp.LoggedOnUser.HasRight(UserRightType.OrganisationView_AllowEditCostBearer))
                return;

            VMFactory.CreateOrganisationVMAsync(ViewModel.SelectedCostBearer.OrganisationOid,
                cb => this.Dispatch(() => BeWoUtils.OpenModalViewWindow<OrganisationVM, OrganisationDC, ServiceInvoiceView>(
                    cb, this, () => this.Dispatch(() => BeWoUtils.UpdateAllViews(ViewModel.SelectedCostBearer)), _OrganisationModalPopUp_OrganisationSavedOrUpdated)));
        }

        private void _OrganisationModalPopUp_OrganisationSavedOrUpdated(object sender, EventArgs<OrganisationVM> e)
        {
            ServiceFacade.DoCustomerServiceAsync(
                s => s.LoadOrganisationCompact(e.Data.DataContract.OrganisationOid.Value),
                p => this.Dispatch(
                    delegate
                    {
                        ViewModel.SelectedCostBearer = p;
                        popupedit_CostBeaerer.Focus();
                        MainControl.CloseCurrentPopUp();
                    }));
        }

        private void Popupedit_supportConcept_OnPreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (!BeWoUtils.CheckPopupEditClickableSpace((PopUpEdit)sender, e) || ViewModel.SelectedSupportConcept == null || !BeWoApp.LoggedOnUser.HasRight(UserRightType.SupportConceptView_Edit))
                return;

            VMFactory.CreateSupportConceptVMAsync(ViewModel.SelectedSupportConcept.SupportConceptOid,
                cb => this.Dispatch(
                            () => BeWoUtils.OpenModalViewWindow<SupportConceptVM, SupportConceptDC, ServiceInvoiceView>(cb, this, 
                            () => this.Dispatch(() => BeWoUtils.UpdateAllViews(ViewModel.SelectedSupportConcept)))));
        }
    }
}