using System;
using Valg.EVA.Skanning.Contracts;
using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.Entity.ReadModel;
using Valg.EVA.Skanning.ServicesModel.ElectionConfig.Model;
using Valg.EVA.Skanning.ServicesModel.Internal.Validation;

namespace Valg.EVA.Skanning.ServicesModel.Internal.CountResult
{
    public class FilterForPersonVoteInclusion
    {
        private readonly FillPercentageRangeChecker rangeChecker;
        private readonly Affiliation affiliation;

        public FilterForPersonVoteInclusion(FillPercentageRangeChecker rangeChecker, Affiliation affiliation)
        {
            this.rangeChecker = rangeChecker;
            this.affiliation = affiliation;
        }

        public bool IsIncluded(BallotPaperFieldValue fieldValueToTest)
        {
            return fieldValueToTest.IsCandidateField() && HasActuallyBeenPersonVoted(fieldValueToTest) 
                && affiliation.CandidateExistsWithinTheAffiliation(fieldValueToTest.FieldIndex.GetValueOrDefault());
        }
        
        private bool HasActuallyBeenPersonVoted(BallotPaperFieldValue personVote)
        {
            var givenByCorrection = IsPersonVotedAsGivenByCorrection(personVote);
            if (givenByCorrection.HasValue)
                return givenByCorrection.Value;

            var givenByScanner = IsPersonVotedAsGivenByScanner(personVote);
            if (givenByScanner.HasValue)
                return givenByScanner.Value;

            return false;
        }

        private bool? IsPersonVotedAsGivenByScanner(BallotPaperFieldValue personVote)
        {
            if (personVote.Value != null)
            {
                var originalValueInt = Convert.ToInt32(personVote.Value);
                return rangeChecker.IsInsideRange(originalValueInt);
            }

            return null;
        }

        private bool? IsPersonVotedAsGivenByCorrection(BallotPaperFieldValue personVote)
        {
            if (personVote.ValueSourceType == ValueSourceType.Verify)
            {
                return personVote.Value == ScannerFieldValueTemplateValues.PersonVoteIsGiven.ToString();
            }

            return null;
        }
    }
}
