using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Navigation;
using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using DevExpress.Data;
using DevExpress.Utils;
using DevExpress.Xpf.Editors.Settings;
using DevExpress.Xpf.Grid;
using Microsoft.Win32;

namespace BeWo.View.Detail
{
	/// <summary>
	///     Interaction logic for AccountingTransactionView.xaml
	/// </summary>
	public partial class AccountingTransactionView : BeWoView
	{
		private AccountingTransactionListVM _VM;

		private bool _sorted;

		public AccountingTransactionView(List<ValueListEntryDC> pPossibleCategories, List<SupportConceptTreeNodeDC> pSupportConceptsTree)
		{
			InitializeComponent();

			InitDateCombos();
			ReloadViewModel();

			DownloadLinkEngine = new DownloadLinkEngine();
			linkExcelExport.NavigateUri = DownloadLinkEngine.GenerateNewExcelLink();

			treesearchview_filter.ResultTree.SelectedItemChanged += (s, e) =>
			{
				ViewModel.FilterNode = treesearchview_filter.ResultTree.SelectedItem as SupportConceptTreeNodeDC;
				OnFilterChanged();
			};

			// combobox_categories.ItemsSource = pPossibleCategories;
			column_category.EditSettings = new ComboBoxEditSettings {ItemsSource = pPossibleCategories};
			pSupportConceptsTree.Sort(
				(x, y) =>
				{
					if (x.CostBearer != null && y.CostBearer != null)
					{
						return x.CostBearer.Name.CompareTo(y.CostBearer.Name);
					}
					if (x.Customer != null && y.Customer != null)
					{
						return (x.Customer.LastName + ", " + x.Customer.FirstName).CompareTo(y.Customer.LastName + ", " + y.Customer.FirstName);
					}

					return x.Description.CompareTo(y.Description);
				});

			// treesearchview_new.List = pSupportConceptsTree;
			treesearchview_filter.List = pSupportConceptsTree;

			RoutedEventHandler lYearFilterChanged = (s, e) =>
			{
				if (!checkbox_yearfilter.IsChecked.Value)
				{
					checkbox_monthfilter.IsChecked = false;
				}
			};
			checkbox_yearfilter.Unchecked += lYearFilterChanged;
			checkbox_yearfilter.Checked += lYearFilterChanged;

			combobox_month.SelectionChanged += (s, e) =>
			{
				ViewModel.FilterSpan = OverviewTimeSpan;
				OnFilterChanged();
			};
			combobox_year.SelectionChanged += (s, e) =>
			{
				ViewModel.FilterSpan = OverviewTimeSpan;
				OnFilterChanged();
			};
			combobox_month.IsEnabledChanged += (s, e) =>
			{
				ViewModel.FilterSpan = OverviewTimeSpan;
				OnFilterChanged();
			};
			combobox_year.IsEnabledChanged += (s, e) =>
			{
				ViewModel.FilterSpan = OverviewTimeSpan;
				OnFilterChanged();
			};

			// HACK: Force the devexpress grid to end editing when the mouse is over savebutton
			// by setting the focus to another element. 
			//this.MouseMove += (s, e) =>
			//    {
			//        if (!this.datagrid_transactions.IsVisible)
			//        {
			//            return;
			//        }

			//        Point p = e.GetPosition(btnSave);

			//        if (p.X >= 0 && p.X < btnSave.ActualWidth && p.Y >= 0 && p.Y < btnSave.ActualHeight)
			//        {
			//            bool b = this.datagrid_transactions.Focus();
			//        }
			//    };

			datagrid_transactions.ColumnsPopulated += datagrid_transactions_ColumnsPopulated;

			if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.AccountingTransactionView_Edit) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.EditAll))
			{
				// GridColumnView cview = datagrid_transactions.View as GridColumnView;
				foreach (GridColumn item in datagrid_transactions.Columns)
				{
					item.AllowEditing = DefaultBoolean.False;
				}
			}

			if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.AccountingTransactionView_Delete) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.DeleteAll))
			{
				datagrid_transactions.Columns[0].Visible = false;
			}
		}

		public DownloadLinkEngine DownloadLinkEngine { get; set; }

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

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

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

		private DateTimeSpan OverviewTimeSpan
		{
			get
			{
				if (!checkbox_yearfilter.IsChecked.Value)
				{
					return null;
				}

				var lResult = new DateTimeSpan();
				if (checkbox_monthfilter.IsChecked.Value)
				{
					lResult.StartDateTime = new DateTime((int) combobox_year.SelectedItem, DateTimeFormatInfo.CurrentInfo.MonthNames.IndexOf((string) combobox_month.SelectedItem) + 1, 1);
					lResult.EndDateTime = lResult.StartDateTime.AddMonths(1);
				}
				else
				{
					lResult.StartDateTime = new DateTime((int) combobox_year.SelectedItem, 1, 1);
					lResult.EndDateTime = lResult.StartDateTime.AddYears(1);
				}

				lResult.EndDateTime = lResult.EndDateTime.AddSeconds(-1);
				return lResult;
			}
		}

		private AccountingTransactionListVM ViewModel
		{
			get { return _VM; }

			set
			{
				DataContext = value;
				value.FilterSpan = OverviewTimeSpan;
				_VM = value;
			}
		}

		protected override void Save()
		{
			var lToDos = new List<Action<IOperationsService>>();

			string lMessage = string.Empty;

			if (ViewModel.AddedCount > 0)
			{
				if (BeWoApp.HasLoggedOnUserRight(new[] {UserRightType.CreateAll, UserRightType.AccountingTransactionView_Create}))
				{
					lToDos.Add(s => s.InsertNewAccountingTransactions(ViewModel.CommitAdded()));
				}
				else
				{
					lMessage += "Sie besitzen nicht die Berechtigung Finanzbuchungen anzulegen.\n";
				}
			}

			if (ViewModel.ChangedCount > 0)
			{
				if (BeWoApp.HasLoggedOnUserRight(new[] {UserRightType.EditAll, UserRightType.AccountingTransactionView_Edit}))
				{
					lToDos.Add(s => s.UpdateAccountingTransactions(ViewModel.CommitChanged()));
				}
				else
				{
					lMessage += "Sie besitzen nicht die Berechtigung Finanzbuchungen zu ändern\n";
				}
			}

			if (ViewModel.RemovedCount > 0)
			{
				if (BeWoApp.HasLoggedOnUserRight(new[] {UserRightType.DeleteAll, UserRightType.AccountingTransactionView_Delete}))
				{
					lToDos.Add(s => s.DeleteAccountingTransactions(ViewModel.GetRemoved().ToDictionary(dc => dc.AccountingTransactionOid.Value, dc => dc.AccountingTransactionVersion.Value)));
				}
				else
				{
					lMessage += "Sie besitzen nicht die Berechtigung Finanzbuchungen zu löschen\n";
				}
			}

			if (lMessage != string.Empty)
			{
				MessageBox.Show(lMessage + "\nWenden Sie sich an den Adminstrator", "Fehlende Berechtigung", MessageBoxButton.OK, MessageBoxImage.Warning);
			}

			if (lToDos.Count > 0)
			{
				ServiceFacade.DoMultipleOperationsServicesAsync(lToDos, delegate { this.Dispatch(ReloadViewModel); });
			}
		}

		private void DeleteButton_Click(object sender, RoutedEventArgs e)
		{
			if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.AccountingTransactionView_Delete) && !BeWoApp.LoggedOnUser.HasRight(UserRightType.DeleteAll))
			{
				MessageBox.Show("Sie besitzen nicht das Recht Finanzbuchungen zu löschen.", "Löschen", MessageBoxButton.OK, MessageBoxImage.Exclamation);
			}
			else
			{
				var lVM = datagrid_transactions.GetCurrentValue<AccountingTransactionVM>();
				if (lVM != null)
				{
					ViewModel.VMList.Remove(lVM);
					BeWoWpfUtils.RefreshDXGrid(datagrid_transactions);
				}
			}
		}

		private void InitDateCombos()
		{
			combobox_month.ItemsSource = DateTimeFormatInfo.CurrentInfo.MonthNames.Where(s => !string.IsNullOrEmpty(s));
			combobox_month.SelectedIndex = DateTime.Now.Month - 1;

			var years = new List<int>();
			for (int i = 0; i <= 10; i++)
			{
				years.Add(DateTime.Now.Year - i);
			}

			combobox_year.ItemsSource = years;
			combobox_year.SelectedItem = DateTime.Now.Year;
		}

		private void OnFilterChanged()
		{
			if (ViewModel != null)
			{
				this.Dispatch(
					delegate
					{
						long? lSupportConceptOid = null;
						long? lCostBearerSupportConceptOid = null;

						if (checkbox_supportconceptfilter.IsChecked.Value)
						{
							var lNode = treesearchview_filter.ResultTree.SelectedItem as SupportConceptTreeNodeDC;
							if (lNode != null && lNode.SupportConcept != null)
							{
								lSupportConceptOid = lNode.SupportConcept.SupportConceptOid;
							}

							if (lNode != null && lNode.SupportConceptCostBearerRelDC != null)
							{
								lCostBearerSupportConceptOid = lNode.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid;
							}
						}

                            var span = this.OverviewTimeSpan;
                            ServiceFacade.DoOperationsServiceAsync(
                                s => s.GetAccountingTransactions(span, lSupportConceptOid, lCostBearerSupportConceptOid), 
                                r => this.Dispatch(
                                    delegate
                                        {
                                            this.ViewModel.DCBackup.AddRange(r.Where(dc => !this.ViewModel.DCBackup.Contains(dc)));
											this.ViewModel.RefreshFilterResult();
                                            this.ViewModel.UpdateSum();
                                        }));
                        });
            }
        }


		public void ReloadViewModel()
		{
			long? lSupportConceptOid = null;
			long? lCostBearerSupportConceptOid = null;


			if (checkbox_supportconceptfilter.IsChecked.Value)
			{
				var lNode = treesearchview_filter.ResultTree.SelectedItem as SupportConceptTreeNodeDC;
				if (lNode != null && lNode.SupportConcept != null)
				{
					lSupportConceptOid = lNode.SupportConcept.SupportConceptOid;
				}

				if (lNode != null && lNode.SupportConceptCostBearerRelDC != null)
				{
					lCostBearerSupportConceptOid = lNode.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid;
				}
			}

			DateTimeSpan lSpan = OverviewTimeSpan;
			VMFactory.CreateAccountingTransactionListVMAsnyc(lSpan, lSupportConceptOid, lCostBearerSupportConceptOid, r => this.Dispatch(delegate { ViewModel = r; }));
		}

		// private void treeview_currentSupportConcepts_Selected(object sender, RoutedEventArgs e)
		// {
		// var lContainer = e.OriginalSource as TreeViewItem;
		// var lItem = treesearchview_new.ResultTree.SelectedItem as SupportConceptTreeNodeDC;
		// if (lItem.NodeType != NodeType.SupportConceptCostBearerRelDC)
		// lContainer.IsSelected = false;
		// else
		// {
		// popup_costBearer.IsOpen = false;
		// popupedit_costBeaerer.Focus();
		// popupedit_costBeaerer.Text = lItem.SupportConcept.ToString() + " - " + lItem.SupportConceptCostBearerRelDC.ToString();
		// ViewModel.NewVM.CostBearerRel = lItem.SupportConceptCostBearerRelDC;
		// }
		// }

		// private void popupedit_costBeaerer_DeleteClick(object sender, RoutedEventArgs e)
		// {
		// popupedit_costBeaerer.Text = string.Empty;
		// ViewModel.NewVM.CostBearerRel = null;
		// }

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

		private void checkbox_supportconceptfilter_CheckedChanged(object sender, RoutedEventArgs e)
		{
			if (ViewModel != null)
			{
				if (checkbox_supportconceptfilter.IsChecked.Value)
				{
					ViewModel.FilterNode = treesearchview_filter.ResultTree.SelectedItem as SupportConceptTreeNodeDC;
				}
				else
				{
					ViewModel.FilterNode = null;
				}
			}
		}

		private void datagrid_transactions_ColumnsPopulated(object sender, RoutedEventArgs e)
		{
			if (!_sorted)
			{
				datagrid_transactions.SortBy(column_bookingdate, ColumnSortOrder.Descending);
			}

			_sorted = true;
		}

		private void linkExcelExport_RequestNavigate(object sender, RequestNavigateEventArgs e)
		{
			var lView = datagrid_transactions.View as TableView;

			var lHeaderCaptions = new List<string>();
			var lContent = new List<List<string>>();

			if (lView != null)
			{
				foreach (GridColumn iCol in lView.VisibleColumns)
				{
					if (!String.IsNullOrEmpty(iCol.HeaderCaption.ToString()))
					{
						lHeaderCaptions.Add(iCol.HeaderCaption.ToString());

						for (int iRowIndex = 0; iRowIndex < datagrid_transactions.VisibleRowCount; iRowIndex++)
						{
							if (lContent.Count <= iRowIndex)
							{
								lContent.Add(new List<string>());
							}

							lContent[iRowIndex].Add(datagrid_transactions.GetCellValue(iRowIndex, iCol).ToStringNullCheck());
						}
					}
				}
			}
			string path = BeWoApp.GetAndCreateUserAppDataPath() + "\\Abschlagszahlungen.xls";

			var sf = new SaveFileDialog {FileName = Path.GetFileName(path), Filter = "Microsoft Excel 97-2003-Arbeitsblatt|*.xls|Alle Dateien|*.*"};
			if (sf.ShowDialog() != true)
				return;
			ServiceFacade.DoDownloadServiceSync(s => BeWoUtils.WriteExcelFile(s.PrepareExcelFile(DownloadLinkEngine.ExcelFileId, lHeaderCaptions, lContent), sf.FileName));


			//string navitageUri = ((Hyperlink)sender).NavigateUri.ToString();
			//BeWoUtils.NavigateToReportUri(navitageUri);
			////System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo((sender as System.Windows.Documents.Hyperlink).NavigateUri.ToString()));

			//// Workaround Hyperlink mit neuem ersetzen, Navigate Uri lässt auf dem alten nicht ändern...
			//this.textblock_link.Inlines.Clear();
			//var lNewLink = new Hyperlink(new Run("Excel Export")) { NavigateUri = DownloadLinkEngine.GenerateNewExcelLink(), Foreground = Brushes.Black, TargetName = "newWindow" };
			//lNewLink.RequestNavigate += this.linkExcelExport_RequestNavigate;
			//this.textblock_link.Inlines.Add(lNewLink);
		}
	}
}