using Valg.EVA.Skanning.ContainerExtensions;
using Valg.EVA.Skanning.UserInterfaceElements.BallotPaperImage;
using Valg.EVA.Skanning.UserInterfaceElements.BallotPaperImage.Events;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using Prism.Commands;
using Valg.EVA.Skanning.JobManagement.Startup.UI.Duplicates.Events;

namespace Valg.EVA.Skanning.JobManagement.Startup.UI.Duplicates
{
    public class ImageNavigatorViewModel : ReactiveViewModel
    {
        private readonly ITypedFactory typedFactory;
        private readonly IDictionary<int, IBallotPaperImageViewModel> ballotPaperImages = new Dictionary<int, IBallotPaperImageViewModel>();
        private IBallotPaperImageViewModel currentBallotPaperImageViewModel;
        private LinkedList<IBallotPaperImageViewModel> linkedListOfImages;
        private List<IndexedImage> indexedImages;
        private string currentImageText;

        private bool isVisible;
        private bool nextButtonEnabled;
        private bool previousButtonEnabled;
        private string currentImageTitle;

        public ImageNavigatorViewModel(ITypedFactory typedFactory)
        {
            this.typedFactory = typedFactory;
        }

        protected override void SubscribeToViewModelSpecificEvents()
        {
            SubscribeToEvent<ViewImagesEvent, ViewImagesEventArgs>(LoadImages);
            SubscribeToEvent<FlipImageEvent, FlipImageEventArgs>(FlipImageEventHandler);
        }

        public IBallotPaperImageViewModel CurrentImage
        {
            get
            {
                return currentBallotPaperImageViewModel;
            }
            set
            {
                currentBallotPaperImageViewModel = value;
                currentBallotPaperImageViewModel.ShowZoomPanelMiniMap = false;
                OnPropertyChanged();
            }
        }

        public ICommand NextImage
        {
            get
            {
                return new DelegateCommand(
                    () =>
                    {
                        if (CurrentImage != null)
                        {
                            var nextImage = linkedListOfImages?.Find(CurrentImage);
                            if (nextImage?.Next != null)
                            {
                                CurrentImage = nextImage.Next.Value;
                                SetCurrentImageInfo();
                            }
                        }
                        SetNavigationButtonStatus();
                    });
            }
        }

        public ICommand PreviousImage
        {
            get
            {
                return new DelegateCommand(
                    () =>
                    {
                        if (CurrentImage != null)
                        {
                            var nextImage = linkedListOfImages?.Find(CurrentImage);
                            if (nextImage?.Previous != null)
                            {
                                CurrentImage = nextImage.Previous.Value;
                                SetCurrentImageInfo();
                            }
                        }
                        SetNavigationButtonStatus();
                    });
            }
        }

        private void SetCurrentImageInfo()
        {
            if (indexedImages.Count > 0)
            {
                var currentIndexedImage = indexedImages.First(x => x.BallotPaperId == CurrentImage.BallotPaperId);
                CurrentImageText = string.Format(Valg.EVA.Skanning.Resources.Language.JobManagementLanguageString.Duplicates_ImageView_XofY, currentIndexedImage.Index, linkedListOfImages.Count);
                CurrentImageTitle = $"{Valg.EVA.Skanning.Resources.Language.JobManagementLanguageString.ShowingBallotId} {currentIndexedImage.BallotId} {Valg.EVA.Skanning.Resources.Language.LanguageString.In} {currentIndexedImage.BoxName.ToLower()}";
            }
        }

        public string CurrentImageText
        {
            get
            {
                return currentImageText;
            }
            set
            {
                currentImageText = value;
                OnPropertyChanged();
            }
        }

        public string CurrentImageTitle
        {
            get
            {
                return currentImageTitle;
            }
            set
            {
                currentImageTitle = value;
                OnPropertyChanged();
            }
        }

        public bool IsVisible
        {
            get { return isVisible; }
            set
            {
                if (isVisible != value)
                {
                    isVisible = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool PreviousButtonEnabled
        {
            get { return previousButtonEnabled; }
            set
            {
                if (previousButtonEnabled != value)
                {
                    previousButtonEnabled = value;
                    OnPropertyChanged();
                }
            }
        }

        public bool NextButtonEnabled
        {
            get { return nextButtonEnabled; }
            set
            {
                if (nextButtonEnabled != value)
                {
                    nextButtonEnabled = value;
                    OnPropertyChanged();
                }
            }
        }

        private void SetNavigationButtonStatus()
        {
            if (linkedListOfImages != null)
            {
                PreviousButtonEnabled = linkedListOfImages.First.Value != CurrentImage;
                NextButtonEnabled = linkedListOfImages.Last.Value != CurrentImage;
            }
        }

        private void FlipImageEventHandler(FlipImageEventArgs flipImageEventArgs)
        {
            foreach (var ballotPaperImageViewModel in ballotPaperImages)
            {
                ballotPaperImageViewModel.Value.CurrentBallotPaperImageIndex = flipImageEventArgs.Index;
            }
        }

        private void LoadImages(ViewImagesEventArgs args)
        {
            ballotPaperImages.Clear();
            if (args.BallotsToSee.Count > 0)
            {
                indexedImages = new List<IndexedImage>();

                var counter = 1;
                foreach (var ballot in args.BallotsToSee)
                {
                    if (!ballotPaperImages.ContainsKey(ballot.BallotPaperId))
                    {
                        var imageViewModel = typedFactory.Create<IBallotPaperImageViewModel>();
                        imageViewModel.BallotPaperId = ballot.BallotPaperId;
                        imageViewModel.BoxCountingId = ballot.BoxCountingId;
                        ballotPaperImages.Add(ballot.BallotPaperId, imageViewModel);

                        indexedImages.Add(new IndexedImage { BallotPaperId = ballot.BallotPaperId, Index = counter, BoxName = ballot.BoxCountingName, BallotId = ballot.Value });
                        counter++;
                    }
                }

                linkedListOfImages = new LinkedList<IBallotPaperImageViewModel>(ballotPaperImages.Values);

                CurrentImage = linkedListOfImages.First.Value;
                SetCurrentImageInfo();

                SetNavigationButtonStatus();

                IsVisible = true;
            }
            else
            {
                IsVisible = false;
            }
        }

        private class IndexedImage
        {
            public int BallotPaperId { get; set; }
            public int Index { get; set; }
            public string BoxName { get; set; }
            public string BallotId { get; set; }
        }
    }
}
