using System;
using System.Windows.Threading;
using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.Services.TransferCounting;
using Valg.EVA.Skanning.UserInterfaceElements;
using Valg.EVA.Skanning.UserInterfaceElements.LightBox;
using Valg.EVA.Skanning.Identity;
using Prism.Commands;
using ReactiveUI;
using System.Windows.Input;
using Valg.EVA.Skanning.Contracts.Security;
using Valg.EVA.Skanning.JobManagement.Startup.Data;

namespace Valg.EVA.Skanning.JobManagement.Startup.UI.TransferOverview
{
    public class TransferOverviewViewModel : ReactiveViewModel, IVotingCategoryAwareViewModel, IPollingDistrictAwareViewModel
    {
        private readonly IDataModel model;
        private readonly ITypedFactory factory;
        private readonly IIdentityProvider identityProvider;
        private readonly ITransferCountingService transferCountingService;

        public TransferOverviewViewModel(
            IDataModel model,
            ITypedFactory factory,
            IIdentityProvider identityProvider,
            ITransferCountingService transferCountingService)
        {
            this.model = model;
            this.factory = factory;
            this.identityProvider = identityProvider;
            this.transferCountingService = transferCountingService;
            ShowTransferDetailsCommand = new DelegateCommand<TransferViewModel>(ShowTransferDetails);
            RestartStatusCheckCommand = new DelegateCommand<TransferViewModel>(RestartStatusCheck);
        }

        public ICommand ShowTransferDetailsCommand { get; set; }
        public ICommand RestartStatusCheckCommand { get; set; }

        public bool AllowedToViewDetails => identityProvider.HasAreaSpecificClaim(ClaimDefinitions.TransferAccessClaimType);

        private void ShowTransferDetails(TransferViewModel transferViewModel)
        {
            if (transferViewModel == null)
                return;

            var viewModel = factory.Create<TransferDetailsViewModel>();
            viewModel.LoadData(
                transferViewModel.CountingId,
                transferViewModel.TransferJobId,
                transferViewModel.CountingName,
                ActivePollingDistrict,
                transferViewModel.CountingType);

            var eventArgs = new LightBoxEventArgs(
                typeof(TransferDetailsPopupView),
                viewModel);
            
            PublishEvent<ShowLightBoxEvent, LightBoxEventArgs>(eventArgs);
        }

        private async void RestartStatusCheck(TransferViewModel transferViewModel)
        {
            await transferCountingService.RefreshUpdatedTimestampOnTransferAsync(transferViewModel.TransferId, identityProvider.GetCurrentUserName(), transferViewModel.Updated);
            await Dispatcher.CurrentDispatcher.BeginInvoke(new Action(model.LoadTransfers));
        }

        private IReactiveCollection<TransferViewModel> GetCompletedCountings()
        {
            var votingCategory = ActiveVotingCategory.Key();

            return model.CompletedCountings.CreateDerivedCollection(
                c =>
                {
                    var viewModel = factory.Create<TransferViewModel>();
                    viewModel.Initialize(c);
                    return viewModel;
                },
                vm => vm.Counting.EmlAreaContextId == ActivePollingDistrict.Id && vm.Counting.VotingCategory == votingCategory);
        }

        private IReactiveCollection<TransferViewModel> completedCountings;

        public IReactiveCollection<TransferViewModel> CompletedCountings => completedCountings ?? (completedCountings = GetCompletedCountings());

        public VotingCategoryType ActiveVotingCategory { get; set; }

        public bool HasOnlyOnePollingDistrict { get; set; }

        public PollingDistrictModel ActivePollingDistrict { get; set; }
    }
}
