using Valg.EVA.Skanning.Entity.SqlConnection;
using Valg.EVA.Skanning.Repositories.Counting;
using System;
using Valg.EVA.Skanning.Contracts.CommonEnums;
using Valg.EVA.Skanning.Diagnostics;

namespace Valg.EVA.Skanning.Commands.ResolveBoxCountingDuplicates
{
    public class ResolveBoxCountingDuplicatesCommandHandler : IHandleCommandsWithReturnValue<ResolveBoxCountingDuplicatesCommand, ResolveBoxCountingDuplicatesCommandResult>
    {
        private readonly ICountingWriteableRepository countingWriteableRepository;
        private readonly TransactionScopeFactory transactionScopeFactory;
        private readonly ICountingRepository countingRepository;

        public ResolveBoxCountingDuplicatesCommandHandler(ICountingWriteableRepository countingWriteableRepository, TransactionScopeFactory transactionScopeFactory, ICountingRepository countingRepository)
        {
            this.countingWriteableRepository = countingWriteableRepository;
            this.transactionScopeFactory = transactionScopeFactory;
            this.countingRepository = countingRepository;
        }

        public ResolveBoxCountingDuplicatesCommandResult CommandResult { get; private set; }

        public void HandleCommand(ResolveBoxCountingDuplicatesCommand command)
        {
            CommandResult = new ResolveBoxCountingDuplicatesCommandResult();

            using (var scope = transactionScopeFactory.GetTransactionScope())
            {
                try
                {
                    if (command.IsInEmergencyMode)
                    {
                        countingWriteableRepository.MarkCountingAsProcessedDuringEmergencMode(command.CountingId);
                    }

                    var currentBoxCounting = countingRepository.GetBoxCounting(command.BarcodeLong, command.BarcodeShort, command.CountingId);

                    if (currentBoxCounting != null && currentBoxCounting.State == BoxCountingState.ResolveDuplicates)
                    {
                        countingWriteableRepository.UpdateBoxCountingState(
                        command.BarcodeLong,
                        command.BarcodeShort,
                        command.CountingId,
                        BoxCountingState.ReadyForVerify, command.LatestConcurrencyToken,
                        BoxCountingState.ResolveDuplicates, command.ChangedBy);
                    }

                    CommandResult.Success = true;

                    scope.Complete();
                }
                catch (Exception e)
                {
                    EvaSkanningEventSource.Log.DuplicatesResolutionFailed(e.ToString());
                    CommandResult.Success = false;
                    CommandResult.Exception = e;
                }
            }
        }
    }
}
