using System;
using System.Windows;
using Valg.EVA.Skanning.BackgroundServices;
using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.UserInterfaceElements.ApplicationEvents;
using Valg.EVA.Skanning.UserInterfaceElements.Help;
using Valg.EVA.Skanning.UserInterfaceElements.LightBox;
using Valg.EVA.Skanning.UserInterfaceElements.Login;
using Valg.EVA.Skanning.UserInterfaceElements.RoleSelector;
using Valg.EVA.Skanning.UserInterfaceElements.Spinner;
using Valg.EVA.Skanning.UserInterfaceElements.TopBar;
using Valg.EVA.Skanning.UserInterfaceElements.MessageBox;
using Valg.EVA.Skanning.Identity;
using System.Windows.Input;
using Prism.Commands;
using Prism.Events;
using Valg.EVA.Skanning.Contracts.Security;
using Valg.EVA.Skanning.UserInterfaceElements;
using Valg.EVA.Skanning.UserInterfaceElements.ApplicationTermination;
using Valg.EVA.Skanning.JobManagement.Startup.DataRefresh;
using Valg.EVA.Skanning.JobManagement.Startup.EmergencyMode;
using Valg.EVA.Skanning.JobManagement.Startup.UI;

namespace Valg.EVA.Skanning.JobManagement.Startup.MainWindow
{
    public class MainWindowViewModel : ViewModelBase, IMainWindowViewModel
    {
        private readonly IEventAggregator eventAggregator;
        private readonly IDataRefresher dataRefresher;
        private readonly ITaskManagerInitializer taskManagerInitializer;
        
        
        
        
        
        private readonly IJobManagementApplication jobManagementApplication;

        private readonly IIdentityProvider identityProvider;
        private readonly ITypedFactory typedFactory;

        private readonly int mainWindowPageIndex = 0;
        private readonly int changeRolePageIndex = 1;
        private int currentMainViewIndex;

        private bool isElectionConfigInstalled;

        private readonly string windowIcon = "/Valg.EVA.Skanning.Assets;component/Images/Icons/EvaJobManagement.ico";

        public MainWindowViewModel(
            ITypedFactory typedFactory,
            IRoleSelectorViewModel roleSelectorViewModel,
            IIdentityProvider identityProvider,
            IEventAggregator eventAggregator,
            ILightBoxViewModel lightBoxViewModel,
            ISpinnerViewModel spinnerViewModel,
            IChangeRoleButtonViewModel changeRoleButtonViewModel,
            IMainViewModel jobManagementMainViewModel,
            IDataRefresher dataRefresher,
            IResetEmergencyModeLinkViewModel resetEmergencyModeLinkViewModel,
            ITaskManagerInitializer taskManagerInitializer,
            IJobManagementApplication jobManagementApplication 
            )
        {
            this.typedFactory = typedFactory;
            this.eventAggregator = eventAggregator;
            this.dataRefresher = dataRefresher;
            this.taskManagerInitializer = taskManagerInitializer;
            this.jobManagementApplication = jobManagementApplication;
            RoleSelectorViewModel = roleSelectorViewModel;
            LightBoxViewModel = lightBoxViewModel;
            ChangeRoleButtonViewModel = changeRoleButtonViewModel;
            SpinnerViewModel = spinnerViewModel;
            this.identityProvider = identityProvider;
            JobManagementMainViewModel = jobManagementMainViewModel;
            ResetEmergencyModeLinkViewModel = resetEmergencyModeLinkViewModel;

            InitializeCommands();
        }

        public int CurrentMainViewIndex
        {
            get { return currentMainViewIndex; }
            set
            {
                currentMainViewIndex = value;
                OnPropertyChanged();
            }
        }

        public ISpinnerViewModel SpinnerViewModel { get; private set; }

        public ILightBoxViewModel LightBoxViewModel { get; private set; }

        public IRoleSelectorViewModel RoleSelectorViewModel { get; private set; }

        public IChangeRoleButtonViewModel ChangeRoleButtonViewModel { get; private set; }

        public IMainViewModel JobManagementMainViewModel { get; private set; }

        public bool IsElectionConfigInstalled
        {
            get { return isElectionConfigInstalled; }
            private set
            {
                isElectionConfigInstalled = value;
                OnPropertyChanged();
            }
        }

        public ICommand RefreshCommand { get; set; }

        public ICommand ShowHelpCommand { get; set; }

        public IResetEmergencyModeLinkViewModel ResetEmergencyModeLinkViewModel { get; private set; }

        public void Initialize(bool electionConfigIsInstalled)
        {
            ChangeRoleButtonViewModel.IsVisible = electionConfigIsInstalled;
            IsElectionConfigInstalled = electionConfigIsInstalled;
        }

        public void Login()
        {
            var loginProcess = typedFactory.Create<LoginProcessViewModel>();
            var loginResult = loginProcess.Login(ClaimDefinitions.JobManagementAccessClaimType, windowIcon, showEmergencyModeConfiguration: true);

            switch (loginResult)
            {
                case LoginResult.AccessGranted:
                    {
                        taskManagerInitializer.Initialize();
                        SetStartTab();
                    }
                    break;

                case LoginResult.RootCertificateMissingError:
                    loginProcess.ShowRootCertificateMissingMessage();
                    break;

                case LoginResult.HasErrors:
                case LoginResult.AccessDenied:
                case LoginResult.Unknown:
                    CloseApplication();
                    break;
            }
        }

        public void ShowElectionConfigMissingWindow()
        {
            var resultDialog = typedFactory.Create<IMessageBox>();

            resultDialog.Initialize(Valg.EVA.Skanning.Resources.Language.JobManagementLanguageString.ElectionConfigMissingTextPart1,
                string.Empty, Valg.EVA.Skanning.Resources.Language.JobManagementLanguageString.ElectionConfigMissingTextPart2, MessageBoxType.Warning, null, new DelegateCommand(CloseApplication));

            var eventArgs = new LightBoxEventArgs(resultDialog as Window);
            PublishEvent<ShowLightBoxEvent, LightBoxEventArgs>(eventArgs);
        }

        private void SetStartTab()
        {
            if (identityProvider.CurrentSelectedRole == null)
            {
                CurrentMainViewIndex = changeRolePageIndex;
            }
            else
            {
                MainWindowRequested(null);
            }
        }

        private void InitializeCommands()
        {
            RefreshCommand = new DelegateCommand(RequestDataRefresh);
            ShowHelpCommand = new DelegateCommand(eventAggregator.ShowHelpWindow);
        }

        protected override void SubscribeToViewModelSpecificEvents()
        {
            SubscribeToEvent<ChangeRolePageRequestedEvent, EventArgs>(ChangeRolePageRequested);
            SubscribeToEvent<MainWindowRequestedEvent, EventArgs>(MainWindowRequested);
        }

        private void RequestDataRefresh()
        {
            if (CurrentMainViewIndex != mainWindowPageIndex)
                return;

            PublishEvent<DataRefreshRequestedEvent, DataRefreshRequestedEventArgs>(new DataRefreshRequestedEventArgs());
        }

        private void ChangeRolePageRequested(EventArgs obj)
        {
            CurrentMainViewIndex = changeRolePageIndex;
        }

        private void MainWindowRequested(EventArgs obj)
        {
            dataRefresher.RefreshAllData();
            CurrentMainViewIndex = mainWindowPageIndex;

            if (!dataRefresher.RefreshingAllDataIsrunning)
            {
                dataRefresher.Start();
            }
        }
        
        private void CloseApplication()
        {
            var terminateRequestedEvent = eventAggregator.GetEvent<ApplicationTerminateRequestedEvent>();
            terminateRequestedEvent.Publish(EventArgs.Empty);
        }
    }
}
