using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.ServicesModel.ServiceContracts.Verification.Read;
using Valg.EVA.Skanning.UserInterfaceElements.Commands;
using System.Collections.Generic;
using Valg.EVA.Skanning.UserInterfaceElements;
using Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper.VerifiableViewModelsCollection;
using Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper.Messaging.Commands;
using Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper.WriteModel;

namespace Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper.Stamp
{
    public class StampVerificationPageViewModel : ViewModelBase, IStampVerificationPageViewModel
    {
        private readonly IWriteModelHub writeModelHub;
        private bool stampIsValid;
        private bool needsVerification;
        private bool isApprovButtonFocused;
        private bool neededVerification;
        private ButtonTypes checkedButton;

        private bool SelectionHasBeenMade { get; set; }

        public StampVerificationPageViewModel(IWriteModelHub writeModelHub)
        {
            this.writeModelHub = writeModelHub;

            RejectStamp = new RelayCommand(param => Reject());
            ApproveStamp = new RelayCommand(param => Approve());
        }

        public enum ButtonTypes { Unknown, YesButton, NoButton }

        public int PageIndex { get; set; }

        public IEnumerable<IViewModelWithVerifiableContent> GetVerificationFields()
        {
            return new IViewModelWithVerifiableContent[] { this };
        }

        public RelayCommand RejectStamp { get; set; }

        public RelayCommand ApproveStamp { get; set; }

        public ButtonTypes CheckedButton
        {
            get
            {
                return checkedButton;
            }
            set
            {
                if (checkedButton != value)
                {
                    checkedButton = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool StampIsValid
        {
            get
            {
                return stampIsValid;
            }
            set
            {
                stampIsValid = value;
                UpdateCheckedButtonValues();
                OnPropertyChanged();
            }
        }

        public void SetModel(StampReadOnly stamp)
        {
            StampIsValid = stamp.IsValid;
            NeedsVerification = !stamp.IsRejectedAsNoOfficalStamp && stamp.NeedsVerification;
            NeededVerification = stamp.NeededVerification;
        }

        public bool IsApprovButtonFocused
        {
            get
            {
                return isApprovButtonFocused;
            }
            set
            {
                isApprovButtonFocused = value;
                OnPropertyChanged();
            }
        }

        public bool IsRejectButtonFocused
        {
            get => !IsApprovButtonFocused;
            set => IsApprovButtonFocused = !value;
        }


        public bool NeedsVerification
        {
            get
            {
                return needsVerification;
            }
            set
            {
                needsVerification = value;
                UpdateCheckedButtonValues();
                OnPropertyChanged();
            }
        }

        public bool NeededVerification
        {
            get { return neededVerification; }
            set
            {
                neededVerification = value;
                OnPropertyChanged();
            }
        }

        public int VerificationOrder { get; set; }

        public void RemainFocusAtThisViewModel()
        {
            BringToFocus();
        }

        public void BringToFocus()
        {
            IsApprovButtonFocused = true; 
            IsApprovButtonFocused = false;
        }

        private void UpdateCheckedButtonValues()
        {
            if (!SelectionHasBeenMade && !NeedsVerification)
            {
                CheckedButton = StampIsValid ? ButtonTypes.YesButton : ButtonTypes.NoButton;
            }
        }

        private void Approve()
        {
            SelectionHasBeenMade = true;
            NeedsVerification = false;
            writeModelHub.AddStampValidityModification(new StampValidityModification(true));
            writeModelHub.SetNotRejected(RejectionReasonsCollections.AllActualRejectionReasons);

            SetVerificationToDone();

            CheckedButton = ButtonTypes.YesButton;
        }

        private void Reject()
        {
            SelectionHasBeenMade = true;
            NeedsVerification = false;
            writeModelHub.AddStampValidityModification(new StampValidityModification(false));
            writeModelHub.SetRejectionReason(RejectionReasonType.NoOfficialStamp, PageIndex);

            SetVerificationToDone();

            CheckedButton = ButtonTypes.NoButton;
        }

        private void SetVerificationToDone()
        {
            bool didNeedVerification = NeededVerification;
            NeedsVerification = false;
            var actionWasCommmitedArgs = new VerificationWasResolvedEventArgs(this, didNeedVerification);

            PublishEvent<VerificationResolvedOnVerifiableViewModelEvent, VerificationWasResolvedEventArgs>(actionWasCommmitedArgs);
        }
    }
}
