using Valg.EVA.Skanning.Entity.ReadModel;
using Valg.EVA.Skanning.Entity.SqlConnection;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Valg.EVA.Skanning.Repositories.Counting
{
    public class CountingRepository : ICountingRepository
    {
        private readonly ISqlConnectionFactory connectionFactory;

        public CountingRepository(ISqlConnectionFactory connectionFactory)
        {
            this.connectionFactory = connectionFactory;
        }

        public BoxCounting GetBoxCounting(string barcodeLong, string barcodeShort, int countingId)
        {
            return connectionFactory.SP_Get<BoxCounting>(
                "Counting_GetBoxCounting",
                new
                {
                    BarcodeLong = barcodeLong,
                    BarcodeShort = barcodeShort,
                    CountingId = countingId
                });
        }

        public BoxCounting GetBoxCountingById(int boxCountingId)
        {
            return connectionFactory.SP_Get<BoxCounting>(
                "Counting_GetBoxCountingById",
                new
                {
                    BoxCountingId = boxCountingId
                });
        }

        public List<Valg.EVA.Skanning.Entity.ReadModel.Counting> GetCountings(string electionEventId, string contestId, string countingEmlAreaContextId)
        {
            return connectionFactory.SP_GetList<Valg.EVA.Skanning.Entity.ReadModel.Counting>(
                "Counting_GetCountingsInContest",
                new
                {
                    ElectionEventId = electionEventId,
                    ContestId = contestId,
                    CountingEmlAreaContextId = countingEmlAreaContextId
                }).ToList();
        }

        public Valg.EVA.Skanning.Entity.ReadModel.Counting GetCountingByBoxCountingId(int boxCountingId)
        {
            return connectionFactory.SP_Get<Valg.EVA.Skanning.Entity.ReadModel.Counting>(
                "Counting_GetCountingByBoxCountingId",
                new
                {
                    BoxCountingId = boxCountingId
                });
        }

        public List<BoxCountingDetails> GetBoxCountingDetails(string electionEventId, string contestId, string countingEmlAreaContextId)
        {
            return connectionFactory
                .SP_GetList<BoxCountingDetails>(
                    "Counting_GetBoxCountingDetails",
                    new
                    {
                        ElectionEventId = electionEventId,
                        ContestId = contestId,
                        CountingEmlAreaContextId = countingEmlAreaContextId
                    })
                .ToList();
        }

        public bool AreThereAnyNonValidBallotPapersInThisCounting(int countingId)
        {
            var top1BallotPaperId = connectionFactory.SP_Execute<int>("Counting_AreThereAnyNonValidBallotPapers", new { CountingId = countingId });
            return top1BallotPaperId > 0;
        }

        public List<BoxCounting> GetBoxCountingsByCountingId(int countingId)
        {
            return connectionFactory.SP_GetList<BoxCounting>(
                "Counting_GetBoxCountingsByCountingId",
                new
                {
                    CountingId = countingId
                })
                .ToList();
        }

        
        
        
        
        
        
        
        
        
        public ActiveCounting GetActiveCounting(string uniqueId, string countingEmlAreaContextId, int? existingCountingId)
        {
            return connectionFactory.SP_Get<ActiveCounting>(
                "Counting_GetActiveCounting", new
                {
                    UniqueId = uniqueId,
                    CountingIdIsSpecified = existingCountingId.HasValue,
                    CountingId = existingCountingId,
                    CountingEmlAreaContextId = countingEmlAreaContextId
                });
        }

        public ScannableCounting[] GetScannableCountings(string uniqueId)
        {
            return connectionFactory.SP_GetList<ScannableCounting>(
                "Counting_GetScannableCountings", new
                {
                    UniqueId = uniqueId
                }).ToArray();
        }

        public Valg.EVA.Skanning.Entity.ReadModel.Counting GetCounting(int countingId)
        {
            return connectionFactory.SP_Get<Valg.EVA.Skanning.Entity.ReadModel.Counting>("Counting_GetCounting", new { CountingId = countingId });
        }

        public ReadOnlyCollection<DuplicateBallotId> GetDuplicatesInCounting(int countingId)
        {
            return connectionFactory.SP_GetList<DuplicateBallotId>("Counting_GetDuplicatesInCounting", new { CountingId = countingId }).ToList().AsReadOnly();
        }

        public Valg.EVA.Skanning.Entity.ReadModel.Counting GetCountingByBallotPaperId(int ballotPaperId)
        {
            return connectionFactory.SP_Get<Valg.EVA.Skanning.Entity.ReadModel.Counting>("Counting_GetCountingBallotPaperId", new { BallotPaperId = ballotPaperId });
        }

        public ReadOnlyCollection<BallotWithBallotId> GetDuplicatedBallotsWithBallotId(int ballotId, int countingId)
        {
            return connectionFactory.SP_GetList<BallotWithBallotId>("Counting_GetBallotsWithBallotId", new { BallotId = ballotId, CountingId = countingId }).ToList().AsReadOnly();
        }
    }
}
