using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Windows;

using BeWo.ServiceProxy;
using BeWo.ViewModel;

using BS.Shared;
using BS.Shared.Extensions;

namespace BeWo.View.Detail
{
    public partial class UserGroupView
    {
        private UserGroupVM _ViewModel;

        public UserGroupView(UserGroupVM pViewModel)
        {
            InitializeComponent();
            ViewModel = pViewModel;
        }

        public override bool IsDirty
        {
            get { return ViewModel != null && ViewModel.IsDirty; }
        }

        public override String Title
        {
            get { return "Benutzergruppen"; }
        }

        private UserGroupVM ViewModel
        {
            get { return _ViewModel; }

            set
            {
                _ViewModel = value;
                DataContext = value;
            }
        }

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

        protected override void Save()
        {
            var lDataContract = ViewModel.CommitToDataContract();
            try
            {
                if (ViewModel.IsNew)
                {
                    ServiceFacade.DoUserServiceAsync(s => s.InsertNewUserGroup(lDataContract), ReloadViewModel, true);
                }
                else
                {
                    ServiceFacade.DoUserServiceAsync(s => s.UpdateUserGroup(lDataContract), ReloadViewModel, true);
                }

                BeWoApp.MainControl.ResetView(UIContext.UserGroup);
            }
            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.");
                ReloadViewModel(lDataContract.UserGroupOid.Value);
            }
        }

        private void ReloadViewModel(long pOID)
        {
            VMFactory.CreateUserGroupVMAsync(
                pOID,
                cb => this.Dispatch(
                    delegate
                    {
                        ViewModel = cb;

                        if (BeWoApp.LoggedOnUser.UserGroups.Contains(cb.DataContract))
                        {
                            ServiceFacade.DoUserServiceAsync(s => s.LoadUser(BeWoApp.LoggedOnUser.UserOid.Value), cb2 => BeWoApp.LoggedOnUser = cb2, true);
                        }
                    }));
        }

        private void button_addRight_Click(object sender, RoutedEventArgs e)
        {
            var addedItems = listbox_possibleRights.SelectedItems.Cast<KeyValuePair<UserRightType, String>>().ToList();

            foreach (var item in addedItems)
            {
                ViewModel.Rights.Add(item.Key);
            }

            ViewModel.Rights.Sort();
        }

        private void button_removeRight_Click(object sender, RoutedEventArgs e)
        {
            var removedItems = listbox_rights.SelectedItems.Cast<KeyValuePair<UserRightType, String>>().ToList();

            var userGroupViewRights = new List<UserRightType> { UserRightType.UserGroupView_Edit, UserRightType.UserGroupView_View };
            var globalRights        = new List<UserRightType> { UserRightType.EditAll, UserRightType.ViewAll };

            var removedRights = removedItems.Select(s => s.Key).ToList();

            var anyUserGroupRights2Remove = userGroupViewRights.Intersect(removedRights).Any();
            var anyGlobalRights2Remove    = globalRights.Intersect(removedRights).Any();

            // sind alle globalRights oder alle userGroupViewRights in der Liste noch vorhanden, kann gelöscht werden

            // mindestens ein Edit-Recht und ein View-Rechts
            var intersection = ViewModel.Rights.Except(removedRights).ToList();

            var minRights = intersection.Contains(UserRightType.UserGroupView_Edit) && intersection.Contains(UserRightType.ViewAll) ||
                            intersection.Contains(UserRightType.UserGroupView_Edit) && intersection.Contains(UserRightType.UserGroupView_View) ||
                            intersection.Contains(UserRightType.EditAll) && intersection.Contains(UserRightType.ViewAll) ||
                            intersection.Contains(UserRightType.EditAll) && intersection.Contains(UserRightType.UserGroupView_View);

            if ((anyUserGroupRights2Remove || anyGlobalRights2Remove) && ViewModel.DataContract.UserGroupOid != null && (!minRights))
            {
                if (ServiceFacade.DoUserServiceSync(a => a.CheckUserGroupIsLastWithUserGroupEditRights(ViewModel.DataContract.UserGroupOid.Value)))
                {
                    MessageBox.Show("Die ausgewählten Rechte können der Benutzergruppe nicht entfernt werden, da sie die einzige Benutzergruppe ist, die dazu berechtigt ist, Benutzergruppen zu verwalten.", "Fehler", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }
            }

            foreach (var item in removedItems)
            {
                ViewModel.Rights.Remove(item.Key);
            }

            ViewModel.Rights.Sort();
        }
    }
}