using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Valg.EVA.Skanning.Contracts.CommonEnums;

namespace Valg.EVA.Skanning.ServicesModel.ServiceContracts.Verification.Read
{
    public class BallotPaper
    {
        public BallotPaper(int id, int boxCountingId, bool ignoreCandidates, int ballotPaperConcurrencyToken, int? verificationIndex, RejectionReasonType rejectionReason, bool isValid,
            BallotPaperType ballotPaperType, ReadOnlyCollection<CandidatePersonVoteReadOnly> candidatePersonVotes, ReadOnlyCollection<RenumberStrikeoutReadOnly> renumberStrikeouts, ReadOnlyCollection<WriteInReadOnly> writeIns, ReadOnlyCollection<WriteInReadOnly> initialWriteIns,
            BallotNumberReadOnly ballotNo, string electionEventId, string electionGroupId, string electionId, string contestId, string affiliationShortCode, StampReadOnly stamp, ReadOnlyCollection<AffiliationNameReadOnly> affiliationNames)
        {
            Id = id;
            BoxCountingId = boxCountingId;
            IgnoreCandidates = ignoreCandidates;
            BallotPaperConcurrencyToken = ballotPaperConcurrencyToken;
            VerificationIndex = verificationIndex;
            RejectionReason = rejectionReason;
            IsValid = isValid;
            BallotPaperType = ballotPaperType;
            CandidatePersonVotes = candidatePersonVotes;
            RenumberStrikeouts = renumberStrikeouts;
            WriteIns = writeIns;
            InitialWriteIns = initialWriteIns;
            BallotNo = ballotNo;
            ElectionEventId = electionEventId;
            ElectionGroupId = electionGroupId;
            ElectionId = electionId;
            ContestId = contestId;
            AffiliationShortCode = affiliationShortCode;
            Stamp = stamp;
            AffiliationNames = affiliationNames;

            if (CandidatePersonVotes == null)
                CandidatePersonVotes = new ReadOnlyCollection<CandidatePersonVoteReadOnly>(new CandidatePersonVoteReadOnly[] { });

            if (RenumberStrikeouts == null)
                RenumberStrikeouts = new ReadOnlyCollection<RenumberStrikeoutReadOnly>(new RenumberStrikeoutReadOnly[] { });

            if (WriteIns == null)
                WriteIns = new ReadOnlyCollection<WriteInReadOnly>(new WriteInReadOnly[] { });
            
            if (InitialWriteIns == null)
                InitialWriteIns = new ReadOnlyCollection<WriteInReadOnly>(new WriteInReadOnly[] { });
        }

        public int Id { get; private set; }
        public int BoxCountingId { get; private set; }
        public bool IgnoreCandidates { get; private set; }
        public int BallotPaperConcurrencyToken { get; private set; }
        public int? VerificationIndex { get; private set; }
        public RejectionReasonType RejectionReason { get; private set; }
        public bool IsValid { get; private set; }
        public BallotPaperType BallotPaperType { get; private set; }
        public BallotNumberReadOnly BallotNo { get; private set; }
        public string ElectionEventId { get; private set; }
        public string ElectionGroupId { get; private set; }
        public string ElectionId { get; private set; }
        public string ContestId { get; private set; }
        public string AffiliationShortCode { get; private set; }
        public StampReadOnly Stamp { get; private set; }

        public IReadOnlyCollection<CandidatePersonVoteReadOnly> CandidatePersonVotes { get; private set; }
        public IReadOnlyCollection<RenumberStrikeoutReadOnly> RenumberStrikeouts { get; private set; }
        public IReadOnlyCollection<WriteInReadOnly> WriteIns { get; private set; }
        public IReadOnlyCollection<WriteInReadOnly> InitialWriteIns { get; private set; }
        public IReadOnlyCollection<AffiliationNameReadOnly> AffiliationNames { get; private set; }

        public CandidatePersonVoteReadOnly GetCandidatePersonVoteForCandidate(int candidateId)
        {
            return CandidatePersonVotes.SingleOrDefault(c => c.CandidateIndex == candidateId);
        }

        public RenumberStrikeoutReadOnly GetRenumberStrikeoutForCandidate(int candidateId)
        {
            return RenumberStrikeouts.SingleOrDefault(c => c.CandidateIndex == candidateId);
        }
    }
}
