using Client.DataStructures;
using Client.Helpers;
using Client.ISServiceRef;
using Client.View;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using WpfAsyncPack.Command;

namespace Client.ViewModel
{
    public class UserRolesViewModel : ViewModelBase
    {

        public ObservableCollection<RoleDto> Roles { get; set; }

        public EmployeeDto SelectedEmployee { get; set; }
            
        public ICommand SelectEmployeeCommand { get; set; }

        public ICommand DeleteRoleCommand { get; set; }
        public ICommand ShowAddRoleCommand { get; set; }

        public UserRolesViewModel()
        {
            _userServiceClient.ClientCredentials.UserName.UserName = UserManager.Instance.CurrentUser.Login;
            _userServiceClient.ClientCredentials.UserName.Password = UserManager.Instance.CurrentUser.Password;
            _userServiceClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

            SelectEmployeeCommand = new RelayCommand(ShowEmployeeSelectWindow);
            DeleteRoleCommand = new AsyncCommand<RoleDto>(RemoveRoleAsync);
            ShowAddRoleCommand = new AsyncCommand(ShowAddRoleAsync);

            PropertyChanged += OnSelectedEmployeeChanged;

            Messenger.Default.Register<NotificationMessage<EmployeeDto>>(this, SelectEmployee);
        }

        private void OnSelectedEmployeeChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(SelectedEmployee))
                Task.Run(async () => await LoadUserRolesAsync(SelectedEmployee.Id));
        }

        private async Task LoadUserRolesAsync(int employeeId)
        {
            if (SelectedEmployee == null) return;

            var user = await _userServiceClient.GetUserByIdAsync(employeeId);

            var roles = user.UserRoles;
            Roles = new ObservableCollection<RoleDto>(roles);
        }

        private void ShowEmployeeSelectWindow()
        {
            var hostWindow = new HostWindow(new EmployeesView(true));
            hostWindow.ShowDialog();
        }

        private void SelectEmployee(NotificationMessage<EmployeeDto> message)
        {
            SelectedEmployee = message.Content;
        }

        private async Task ShowAddRoleAsync(object param = null)
        {
            if (SelectedEmployee == null)
                return;

            var addRoleWindow = new AddRoleView(SelectedEmployee);

            addRoleWindow.ShowDialog();

            await LoadUserRolesAsync(SelectedEmployee.Id);
        }

        private async Task RemoveRoleAsync(RoleDto role)
        {
            var toRemove = Roles.First(x => x.Identificator == role.Identificator);
            Roles.Remove(toRemove);

            var user = await _userServiceClient.GetUserByIdAsync(SelectedEmployee.Id);

            var roleIds = Roles.Select(x => x.Id).ToList();
            await _userServiceClient.UpdateUserWithRolesAsync(user, roleIds);

            await LoadUserRolesAsync(SelectedEmployee.Id);
        }

        UserServiceClient _userServiceClient = new UserServiceClient();
    }
}
