using System.ServiceModel;
using System.Windows;
using System.Windows.Input;
using BeWo.Controls;
using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.ViewModel;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;

namespace BeWo.View.Detail
{
	/// <summary>
	///     Interaction logic for UserRightsView.xaml
	/// </summary>
	public partial class UserView : BeWoView
	{
		private UserVM _ViewModel;

		public UserView(UserVM pViewModel)
		{
			InitializeComponent();
			ViewModel = pViewModel;

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

		public override bool IsDirty
		{
			get { return ViewModel != null && (ViewModel.IsDirty && !popup_changePassword.IsOpen); }
		}

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

		internal UserVM ViewModel
		{
			get { return _ViewModel; }

			set
			{
				_ViewModel = value;
				DataContext = value;
				if (!value.IsNew)
				{
					grid_passwordExistingUser.Visibility = Visibility.Visible;
				}
			}
		}

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

		protected override void Save()
		{
			if (ViewModel.IsNew)
			{
				if (string.IsNullOrEmpty(passwordbox_password.Password))
				{
					MessageBox.Show("Geben Sie ein Passwort an", "Passwort", MessageBoxButton.OK, MessageBoxImage.Asterisk);
					return;
				}

				if (passwordbox_password.Password != passwordbox_passwordRepeat.Password)
				{
					MessageBox.Show("Die Passwörter stimmen nicht überein", "Passwort", MessageBoxButton.OK, MessageBoxImage.Asterisk);
					return;
				}

				if (ViewModel.Employee == null)
				{
					MessageBox.Show("Bitte geben Sie einen Mitarbeiter an.", "Speichern nicht möglich", MessageBoxButton.OK, MessageBoxImage.Asterisk);
					return;
				}
			}

			UserDC lUser = ViewModel.CommitToDataContract();
			try
			{
				lUser.NewPassword = passwordbox_password.Password;
				if (ViewModel.IsNew)
				{
					ServiceFacade.DoUserServiceAsync(s => s.InsertNewUser(lUser), ReloadViewModel, true);
				}
				else
				{
					ServiceFacade.DoUserServiceAsync(s => s.UpdateUser(lUser), UserUpdated, true);
				}
				BeWoApp.MainControl.ResetView(UIContext.User);
			}
			catch (FaultException<BeWoFault> ex)
			{
				if (ex.Detail.FaultType == BeWoFaultType.LoginNameTaken)
				{
					MessageBox.Show("Der Login Name ist bereits vergeben", "Login", MessageBoxButton.OK, MessageBoxImage.Asterisk);
					return;
				}

				// TODO 
			}
		}

		private void ClearEditPasswordPopUp()
		{
			textblock_editFailures.Text = string.Empty;
			passwordbox_editOldPassword.Clear();
			passwordbox_editPassword.Clear();
			passwordbox_editPasswordRepeat.Clear();
		}

		private void EmployeeSearchView_EmployeeSelected(object sender, EventArgs<CompactEmployeeDC> e)
		{
			popup_employee.IsOpen = false;
			ViewModel.Employee = e.Data;
		}

		private void ReloadViewModel(long pOid)
		{
			if (pOid == -1)
			{
				this.Dispatch(
					delegate { MessageBox.Show("Leider besitzen Sie nicht genügend Lizenzen um einen neuen Benutzer anzulegen!", "Benutzer anlegen", MessageBoxButton.OK, MessageBoxImage.Information); });
			}
			else
			{
				VMFactory.CreateUserVMAsync(
					pOid,
					cb => this.Dispatch(
						delegate
						{
							ViewModel = cb;
							if (BeWoApp.LoggedOnUser.Equals(cb.DataContract))
							{
								BeWoApp.LoggedOnUser = cb.DataContract;
							}
						}));
			}
		}

		private void UserUpdated(long pOid)
		{
			if (pOid == BeWoApp.LoggedOnUser.UserOid)
			{
				BeWoApp.UserName = ViewModel.DataContract.LoginName;
			}

			ReloadViewModel(pOid);
		}

		private void button_addGroup_Click(object sender, RoutedEventArgs e)
		{
			ViewModel.UserGroups.Add((UserGroupDC) listbox_possibleGroups.SelectedItem);
		}

		private void button_cancelEditPassword_Click(object sender, RoutedEventArgs e)
		{
			popup_changePassword.IsOpen = false;
			ClearEditPasswordPopUp();
		}

		private void button_changePassword_Click(object sender, RoutedEventArgs e)
		{
			if (BeWoApp.LoggedOnUser.HasRight(UserRightType.UserView_AllowChangePassword))
			{
				lblOldPassword.Visibility = Visibility.Collapsed;
				passwordbox_editOldPassword.Visibility = Visibility.Collapsed;
			}

			popup_changePassword.IsOpen = true;
		}

		private void button_removeGroup_Click(object sender, RoutedEventArgs e)
		{
			ViewModel.UserGroups.Remove((UserGroupDC) listbox_groups.SelectedItem);
		}

		private void button_saveEditPassword_Click(object sender, RoutedEventArgs e)
		{
			string oldPw = passwordbox_editOldPassword.Password;
			string newPw = passwordbox_editPassword.Password;

			if (string.IsNullOrWhiteSpace(newPw))
			{
				textblock_editFailures.Text = "Bitte geben Sie ein neues Passwort ein!";
				MessageBox.Show(textblock_editFailures.Text, "Ändern des Passworts fehlgeschlagen", MessageBoxButton.OK, MessageBoxImage.Information);
				return;
			}

			if (newPw != passwordbox_editPasswordRepeat.Password)
			{
				textblock_editFailures.Text = "Die Passwörter stimmen nicht überein!";
				MessageBox.Show(textblock_editFailures.Text, "Ändern des Passworts fehlgeschlagen", MessageBoxButton.OK, MessageBoxImage.Information);
				return;
			}

			if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.UserView_AllowChangePassword))
			{
				var result = ServiceFacade.DoUserServiceSync(s => s.CheckPassword(ViewModel.DataContract.UserOid.Value, oldPw, newPw));

				if (!string.IsNullOrEmpty(result))
				{
					textblock_editFailures.Text = result;
					MessageBox.Show(textblock_editFailures.Text, "Ändern des Passworts fehlgeschlagen", MessageBoxButton.OK, MessageBoxImage.Information);
					return;
				}
			}
			else
			{
				oldPw = ViewModel.DataContract.HashedPassword;
			}

			
			

			ServiceFacade.DoUserServiceAsync(
				s1 => s1.ChangePassword(ViewModel.DataContract.LoginName, ViewModel.DataContract.UserVersion.Value, oldPw, newPw),
				r1 =>
				{
					if (ViewModel.DataContract.UserOid == BeWoApp.LoggedOnUser.UserOid)
					{
						BeWoApp.UserPassword = newPw;
					}

					ServiceFacade.DoUserServiceAsync(
						s2 => s2.LoadUser(ViewModel.DataContract.UserOid.Value),
						r2 => this.Dispatch(
							delegate
							{
								ViewModel.DataContract.UserVersion = r2.UserVersion;
								ViewModel.DataContract.HashedPassword = r2.HashedPassword;

								popup_changePassword.IsOpen = false;
								ClearEditPasswordPopUp();
							}),
						true);
				},
				true);
		}

		private void popupedit_employee_DeleteClick(object sender, RoutedEventArgs e)
		{
			ViewModel.Employee = null;
		}

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

		private void tabitem_documents_Selected(object sender, RoutedEventArgs e)
		{
			if (ViewModel.IsNew)
			{
				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.ApplicationUser, ViewModel.DataContract.UserOid.Value);
			}
		}

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

			VMFactory.CreateEmployeeVMAsync(ViewModel.Employee.EmployeeOid,
				cb => this.Dispatch(
					() => BeWoUtils.OpenModalViewWindow<EmployeeVM, EmployeeDC, UserView>(cb, this, () => this.Dispatch(
						() => BeWoUtils.UpdateAllViews(ViewModel.Employee)))));
		}
	}
}