using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Unity.Interception.Utilities;
using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.Entity.ReadModel;
using Valg.EVA.Skanning.Entity.WriteModel;
using Valg.EVA.Skanning.Repositories.BallotPaper;
using Valg.EVA.Skanning.ServicesModel.Internal.Verification;


namespace Valg.EVA.Skanning.Commands.SaveBallotPaperVerifications
{
    public class FieldValueOperationsHelper
    {
        private readonly IInitialFieldValuesResolver initialFieldValuesResolver;
        private readonly IBallotPaperWritableRepository ballotPaperWritableRepository;

        public FieldValueOperationsHelper(IInitialFieldValuesResolver initialFieldValuesResolver, IBallotPaperWritableRepository ballotPaperWritableRepository)
        {
            this.initialFieldValuesResolver = initialFieldValuesResolver;
            this.ballotPaperWritableRepository = ballotPaperWritableRepository;
        }

        public void ResetFieldValues(int ballotPaperId, List<FieldType> fieldTypesToReset, ReadOnlyCollection<BallotPaperFieldValue> currentFieldValues)
        {
            var initialFieldValues = initialFieldValuesResolver.GetInitialFieldValues(ballotPaperId);

            var resetFieldsOriginatingFromScanOrInterpret = initialFieldValues.Where(f => fieldTypesToReset.Contains(f.FieldType)).ToArray();
            resetFieldsOriginatingFromScanOrInterpret.ForEach(f => InsertBallotPaperFieldValue(f.Value, f.BallotPaperFieldId, f.ValueSourceType, f.CreatedBy, f.NeedsVerification));

            var idsAlreadyReset = resetFieldsOriginatingFromScanOrInterpret.Select(v => v.BallotPaperFieldId).ToList();
            var resetFieldsOriginatingFromVerifyOnly = currentFieldValues.Where(f => fieldTypesToReset.Contains(f.FieldType)
                                                                                     && f.ValueSourceType == ValueSourceType.Verify
                                                                                     && !idsAlreadyReset.Contains(f.BallotPaperFieldId));

            resetFieldsOriginatingFromVerifyOnly.ForEach(f => ResetBallotPaperFieldValue(f.BallotPaperFieldId)); 
        }

        private void ResetBallotPaperFieldValue(int ballotPaperFieldId)
        {
            ballotPaperWritableRepository.ResetBallotPaperFieldValue(new BallotPaperFieldValueReset { BallotPaperFieldId = ballotPaperFieldId });
        }

        public void InsertBallotPaperField(string value, int ballotPaperId, int? fieldIndex, FieldType fieldType, string createdBy)
        {
            ballotPaperWritableRepository.InsertBallotPaperField(
                new BallotPaperFieldInsert
                {
                    BallotPaperId = ballotPaperId,
                    CreatedBy = createdBy,
                    FieldIndex = fieldIndex,
                    NeedsVerification = false,
                    FieldType = fieldType,
                    Value = value,
                    ValueSourceTypeId = ValueSourceType.Verify
                });
        }

        public void InsertBallotPaperFieldValue(string value, int ballotPaperFieldId, ValueSourceType valueSourceType, string createdBy, bool needsVerification = false)
        {
            ballotPaperWritableRepository.InsertBallotPaperFieldValue(new BallotPaperFieldValueInsert
            {
                BallotPaperFieldId = ballotPaperFieldId,
                ValueSourceTypeId = valueSourceType,
                Value = value,
                CreatedBy = createdBy,
                NeedsVerification = needsVerification,
            });
        }
    }
}
