using System.Collections.Generic;

namespace Valg.EVA.Skanning.Verify.Startup.VerifyBallotPaper
{
    public class CurrentInfo
    {
        public LinkedList<int> PreviouslyVisitedBallotPapers { get; } = new LinkedList<int>();
        public int CurrentBoxCountingId { get; set; }
        public LinkedListNode<int> CurrentBallotPaperId { get; set; }
        public bool DataWasPreloaded { get; set; }
        public bool CanAdvanceToPrevious => CurrentBallotPaperId != null && CurrentBallotPaperId.Previous != null;

        public bool IsAtEndOfContinuousStreamOfUnverifiedBallotPapers()
        {
            return CurrentBallotPaperId != null && CurrentBallotPaperId.Next == null && !DataWasPreloaded;
        }

        public bool IsAtEndOfPreloadedStreamOfBallotPapers()
        {
            return CurrentBallotPaperId != null && CurrentBallotPaperId.Next == null && DataWasPreloaded;
        }

        public AdvanceRules DetermineForwardAdvanceRules()
        {
            var advanceRules = new AdvanceRules();

            var atBeginning = CurrentBallotPaperId == null;
            if (atBeginning)
            {
                advanceRules.CanAdvance = true;

                if (DataWasPreloaded)
                {
                    advanceRules.BallotPaperIdToAdvanceTo = PreviouslyVisitedBallotPapers.First;
                }
                else
                {
                    advanceRules.GetNewBallotPaper = true;
                }
            }
            else
            {
                if (IsAtEndOfContinuousStreamOfUnverifiedBallotPapers())
                {
                    advanceRules.CanAdvance = true;
                    advanceRules.GetNewBallotPaper = true;
                }
                else if (IsAtEndOfPreloadedStreamOfBallotPapers())
                {
                    advanceRules.BoxVerificationIsComplete = true;
                }
                else
                {
                    advanceRules.BallotPaperIdToAdvanceTo = CurrentBallotPaperId.Next;
                    advanceRules.CanAdvance = true;
                }
            }

            return advanceRules;
        }

        public void Preload(int[] ballotPaperIds)
        {
            DataWasPreloaded = true;

            foreach (var ballotPaperId in ballotPaperIds)
            {
                PreviouslyVisitedBallotPapers.AddLast(ballotPaperId);
            }
        }

        public void Reset(int boxCountingId)
        {
            CurrentBoxCountingId = boxCountingId;
            PreviouslyVisitedBallotPapers.Clear();
            DataWasPreloaded = false;
            CurrentBallotPaperId = null;
        }

        public bool HasPreviouslyLoadedBallotpapers()
        {
            return CurrentBallotPaperId.List.Count > 0;
        }
    }
}
