using Valg.EVA.Skanning.ServicesModel.ServiceContracts.Verification.Read;
using Valg.EVA.Skanning.UserInterfaceElements;
using Valg.EVA.Skanning.UserInterfaceElements.ApplicationEvents;
using Valg.EVA.Skanning.UserInterfaceElements.TopBar;
using Valg.EVA.Skanning.UserInterfaceElements.Commands;
using Valg.EVA.Skanning.Identity;
using Valg.EVA.Skanning.Services.Count;
using Valg.EVA.Skanning.Services.Verification;
using System;
using System.Windows.Input;
using Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper;
using Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper.Messaging.Commands;

namespace Valg.EVA.Skanning.Verify.Startup.BoxComplete
{
    public class BoxCompleteViewModel : ViewModelBase, IBoxCompleteViewModel
    {
        private readonly IVerificationService verificationService;
        private readonly ICountingService countingService;
        private readonly IIdentityProvider identityProvider;
        private bool? isNextBoxButtonFocused;

        public BoxCompleteViewModel(IVerificationService verificationService, ICountingService countingService, BoxCountingInformationViewModel boxCountingInformationViewModel, IIdentityProvider identityProvider)
        {
            this.verificationService = verificationService;
            this.countingService = countingService;
            BoxCountingInformationViewModel = boxCountingInformationViewModel;
            this.identityProvider = identityProvider;
            GoToStartPageCommand = new RelayCommand(param => GoToStartPage());
            GetNextBoxToVerifyCommand = new RelayCommand(param => GetNextBoxToVerify());
            GoToLastVerifiedBallotPageCommand = new RelayCommand(param => GoToLastVerifiedBallotPage());
            boxCountingInformationViewModel.SetAlwaysVisible();
        }

        protected override void SubscribeToViewModelSpecificEvents()
        {
            SubscribeToEvent<BoxVerificationCompletedEvent, EventArgs>(SetFocusOnNextBoxButton);
        }

        private void SetFocusOnNextBoxButton(EventArgs eventArgs)
        {
            DelayedFocusSetter.SetFocus(() => IsNextBoxButtonFocused = true);
        }

        public ICommand GoToStartPageCommand { get; }

        public ICommand GetNextBoxToVerifyCommand { get; }

        public ICommand GoToLastVerifiedBallotPageCommand { get; private set; }

        public string BoxCompleteHeading => Resources.Language.VerifyLanguageString.BoxComplete_Heading;

        public string GoToStartPageButtonText => Resources.Language.VerifyLanguageString.BoxComplete_GoToStartPage;

        public string GoToLastVerifiedBallotPageButtonText => Resources.Language.VerifyLanguageString.BoxComplete_GoToLastVerifiedBallotPage;

        public string GetNextBoxButtonText => Resources.Language.VerifyLanguageString.BoxComplete_GetNextBox;

        public BoxCountingInformationViewModel BoxCountingInformationViewModel { get; }

        public bool? IsNextBoxButtonFocused
        {
            get { return isNextBoxButtonFocused; }
            set
            {
                isNextBoxButtonFocused = value;
                OnPropertyChanged();
            }
        }

        private void GoToStartPage()
        {
            PublishEvent<MainWindowRequestedEvent, EventArgs>(EventArgs.Empty);
        }

        private void GetNextBoxToVerify()
        {
            var nextBox = verificationService.GetFirstBoxAggregatedStatusForVerify(GetCurrentContestId(), 
                identityProvider.CurrentSelectedRole.CountingEmlAreaContextId,
                identityProvider.CurrentSelectedRole.Area.EmlAreaContextId, identityProvider.CurrentSelectedRole.Area.ElectionEventId);

            if (nextBox.NumberOfBallotPapers > 0)
            {
                PublishBoxIsSelectedForVerifyEvent(nextBox);
            }
            else
            {
                GoToStartPage();
            }
        }

        private string GetCurrentContestId()
        {
            return identityProvider.CurrentSelectedRole?.ContestId;
        }

        private void PublishBoxIsSelectedForVerifyEvent(BoxAggregatedStatusForVerify boxAggregatedStatusForVerify)
        {
            var boxEventArguments = new BoxEventArgs
            {
                BoxCountingId = boxAggregatedStatusForVerify.BoxCountingId,
                BoxNumber = boxAggregatedStatusForVerify.BoxNumber,
                OriginatingLocation = boxAggregatedStatusForVerify.OriginatingLocation,
                VotingCategoryName = VotingCategoryMapping.LocaleName(boxAggregatedStatusForVerify.VotingCategoryType),
                Counting = countingService.GetCountingByBoxCountingId(boxAggregatedStatusForVerify.BoxCountingId)
            };
            
            PublishEvent<BoxIsSelectedForVerifyEvent, BoxEventArgs>(boxEventArguments);
        }

        private void GoToLastVerifiedBallotPage()
        {
            PublishEvent<VerifyPreviousVerifiedBallotPaperEvent, EventArgs>(EventArgs.Empty);
        }
    }
}
