using System.Linq;
using System.Text.RegularExpressions;
using BallotTemplates;
using InterpreterLibrary.Models;

namespace InterpreterLibrary.Processing
{
    public class BallotOutputValidator
    {
        private readonly BallotPaperOutput _dataToValidate;
        private readonly BallotTemplate _template;

        public BallotOutputValidator(BallotPaperOutput dataToValidate, BallotTemplate template)
        {
            _dataToValidate = dataToValidate;
            _template = template;
            Validate();
        }

        public ValidationResult ValidationResult { get; } = new ValidationResult();

        private void Validate()
        {
            ValidationResult.IsValid = true;

            if (_dataToValidate.Type == BallotType.Ukjent)
            {
                ValidationResult.IsValid = false;
                ValidationResult.Issues.Add(new BallotIssue
                {
                    Description = "Ballot paper didn't match any template",
                    Type = IssueType.NotIdentified
                });
                return;
            }

            var ballotNo = _template.Inside.TextFields.Find(tf => tf.Id == "BallotNo");
            if (!Regex.IsMatch(_dataToValidate.BallotNo.InterpretedText, ballotNo.Pattern))
            {
                ValidationResult.Issues.Add(new BallotIssue
                {
                    Type = IssueType.BallotNo,
                    Description = $"Seddelnummeret {_dataToValidate.BallotNo} har feil format"
                });
                ValidationResult.IsValid = false;
            }

            var ballotId = _template.Inside.TextFields.Find(tf => tf.Id == "BallotId");
            if (!Regex.IsMatch(_dataToValidate.BallotId.InterpretedText, ballotId.Pattern))
            {
                ValidationResult.Issues.Add(new BallotIssue
                {
                    Type = IssueType.BallotId,
                    Description = $"Seddel-id {_dataToValidate.BallotId} har feil format"
                });
                ValidationResult.IsValid = false;
            }
            if (_dataToValidate.StampFillPercentages.First() < _template.Outside.StampRegion.ThresholdPercent)
            {
                ValidationResult.Issues.Add(new BallotIssue
                {
                    Type = IssueType.MissingStamp,
                    Description = "Gyldig stempel mangler"
                });
                ValidationResult.IsValid = false;
            }

            var renumberings = from rnf in _template.Inside.RenumberingFields.Items
                join rn in _dataToValidate.Renumberings on rnf.CandidateNumber equals rn.CandidateNumber
                select new
                {
                    rn.CandidateNumber,
                    rn.Text,
                    rnf.Pattern
                };

            foreach (var rn in renumberings)
                if (!int.TryParse(rn.Text, out int _))
                {
                    ValidationResult.Issues.Add(new BallotIssue
                    {
                        Type = IssueType.InvalidRenumbering,
                        Description = $"Kan ikke renummerere kandidat {rn.CandidateNumber} til \"{rn.Text}\""
                    });
                    ValidationResult.IsValid = false;
                }
        }
    }
}
