using System;

namespace Valg.EVA.Skanning.ServicesModel.Internal.BallotNumber
{
    public static class BallotNumberSplitter
    {
        public const int ElectionEventIdStartIndex = 0;
        public const int LengthOfElectionEventId = 6;

        public const int ElectionGroupIdStartIndex = 6;
        public const int LengthOfElectionGroupId = 2;

        public const int ElectionIdStartIndex = 8;
        public const int LengthOfElectionId = 2;

        public const int ContestIdStartIndex = 10;
        public const int LengthOfContestId = 6;

        public const int AffiliationShortCodeStartIndex = 16;
        public const int LengthOfAffiliationShortCode = 4;

        public const int BallotNumberControlDigitStartIndex = 20;
        public const int LengthOfControlDigit = 2;

        public const int TotalLengthOfBallotNumber = 22;

        public static string GetElectionEventId(string ballotNo)
        {
            ThrowExceptionIfNotNumbersAndNotInRange(ballotNo);
          
            return ballotNo.Substring(ElectionEventIdStartIndex, LengthOfElectionEventId);
        }

        public static string GetElectionGroupId(string ballotNo)
        {
            ThrowExceptionIfNotNumbersAndNotInRange(ballotNo);
          
            return ballotNo.Substring(ElectionGroupIdStartIndex, LengthOfElectionGroupId);
        }

        public static string GetElectionId(string ballotNo)
        {
            ThrowExceptionIfNotNumbersAndNotInRange(ballotNo);

            return ballotNo.Substring(ElectionIdStartIndex, LengthOfElectionId);
        }

        public static string GetContestId(string ballotNo)
        {
            ThrowExceptionIfNotNumbersAndNotInRange(ballotNo);

            return ballotNo.Substring(ContestIdStartIndex, LengthOfContestId);
        }

        public static string GetAffiliationShortCode(string ballotNo)
        {
            ThrowExceptionIfNotNumbersAndNotInRange(ballotNo);

            return ballotNo.Substring(AffiliationShortCodeStartIndex, LengthOfAffiliationShortCode);
        }

        private static void ThrowExceptionIfNotNumbersAndNotInRange(string ballotNo)
        {
            if (!string.IsNullOrWhiteSpace(ballotNo) && ballotNo.Length == TotalLengthOfBallotNumber)
            {
                decimal result;
                var success = decimal.TryParse(ballotNo, out result);
                if (!success)
                {
                    throw new ArgumentException("BallotNo was not valid, a valid ballotNo is required in this function");                    
                }
            }
            else
            {
                throw new ArgumentException("BallotNo was not valid, a valid ballotNo is required in this function");
            }
        }

        public static string ContestId(this string ballotNo)
        {
            return GetContestId(ballotNo);
        }

        public static string AffiliationShortCode(this string ballotNo)
        {
            return GetAffiliationShortCode(ballotNo);
        }

        public static string ElectionEventId(this string ballotNo)
        {
            return GetElectionEventId(ballotNo);
        }

        public static string ElectionGroupId(this string ballotNo)
        {
            return GetElectionGroupId(ballotNo);
        }

        public static string ElectionId(this string ballotNo)
        {
            return GetElectionId(ballotNo);
        }
    }
}
