using System;
using System.Collections.Generic;
using System.Linq;
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.BallotNumber;
using Valg.EVA.Skanning.ServicesModel.Internal.Interpreter.Modifications;
using Valg.EVA.Skanning.ServicesModel.Internal.SystemSettings;

namespace Valg.EVA.Skanning.ServicesModel.Internal.Interpreter
{
    public class BlankBallotInterpreter
    {
        private readonly ISystemSettingsProvider settingsProvider;

        public BlankBallotInterpreter(ISystemSettingsProvider settingsProvider)
        {
            this.settingsProvider = settingsProvider;
        }

        public void CheckIntegrity(BallotPaperInBoxCounting ballotPaper, IReadOnlyCollection<BallotPaperFieldValue> ballotPaperFieldValues, 
                                   InterpreterModificationBuffer modificationBuffer, string boxBarcodeLong, BallotPaperType ballotPaperType, CountingType countingType)
        {
            var ballotNumberField = ballotPaperFieldValues.GetBallotNumberField();

            if (!ballotNumberField.NeedsVerification && IsBlankAffiliation(ballotNumberField.Value))
            {
                if (settingsProvider.GetShowBlankBallotInVerification())
                {
                    ShowBlankBallotInVerifyWhenCountingIsFinal(ballotPaper, ballotPaperFieldValues, modificationBuffer, countingType);
                }
                else if(!ballotPaperType.IsGeneralBallotPaperType())  
                {
                    if (ballotPaperType.IsBlankBallotPaperType())
                    {
                        CheckIfBlankBallotHasBeenModifiedByVoter(ballotPaper, ballotPaperFieldValues, modificationBuffer, countingType);
                    }
                    else
                    {
                        
                        ShowBlankBallotInVerifyWhenCountingIsFinal(ballotPaper, ballotPaperFieldValues, modificationBuffer, countingType);
                    }
                }
            }
        }

        private static void CheckIfBlankBallotHasBeenModifiedByVoter(
               BallotPaperInBoxCounting ballotPaper, IReadOnlyCollection<BallotPaperFieldValue> ballotPaperFieldValues,
               InterpreterModificationBuffer modificationBuffer, CountingType countingType)
        {
            var candidateFields = ballotPaperFieldValues.Where(p => p.IsCandidateField()).ToArray();

            if (candidateFields.Any())
            {
                var fieldWithMostFillPercentage = candidateFields.OrderByDescending(p => Convert.ToInt32(p.Value)).FirstOrDefault();

                if (fieldWithMostFillPercentage != null && fieldWithMostFillPercentage.Value != "0")
                {
                    ShowBlankBallotInVerifyWhenCountingIsFinal(ballotPaper, ballotPaperFieldValues, modificationBuffer, countingType);
                }
            }
        }

        private static void ShowBlankBallotInVerifyWhenCountingIsFinal(BallotPaperInBoxCounting ballotPaper, IReadOnlyCollection<BallotPaperFieldValue> ballotPaperFieldValues, InterpreterModificationBuffer modificationBuffer, CountingType countingType)
        {
            if (countingType == CountingType.Final)
            {
                modificationBuffer.MarkFieldToNeedVerification(ballotPaperFieldValues.GetBallotNumberField());
            }

            modificationBuffer.SetBallotPaperToBeMarkedAsIgnoreCandidates(ballotPaper);
            modificationBuffer.SetCorrectionFieldsToNotNeedingVerification(ballotPaperFieldValues);
        }

        private static bool IsBlankAffiliation(string ballotNumber)
        {
            return Affiliation.IsProposedShortCodeBlankAffiliation(ballotNumber.AffiliationShortCode());
        }
    }
}
