using Autofac;
using FluentValidation;
using GreenTree.Nachtragsmanagement.Core;
using GreenTree.Nachtragsmanagement.Services.Appendix;
using GreenTree.Nachtragsmanagement.Services.Deviation;
using GreenTree.Nachtragsmanagement.Services.Site;
using GreenTree.Nachtragsmanagement.Web.Models.Deviation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GreenTree.Nachtragsmanagement.Web.Validation.Deviation
{
    public class DeviationDataModelValidator : AbstractValidator<DeviationDataModel>
    {
        public DeviationDataModelValidator()
        {
            RuleFor(m => m.CustomNumber)
                .NotEmpty()
                    .WithMessage("Nummer wird benötigt")
                .MaximumLength(10)
                    .WithMessage("Muss unter 10 Zeichen sein");

            RuleFor(m => m)
                .Must(m => CustomNumberDoesNotExistInSite(m))
                    .WithMessage("VA-Nummer in Baustelle bereits vorhanden.");

            RuleFor(m => m.Description)
                .NotEmpty()
                    .WithMessage("Beschreibung wird benötigt");

            RuleFor(m => m.ReceiptDate)
                .NotEmpty()
                    .WithMessage("Einreichdatum wird benötigt");

            RuleFor(m => m.StatusId)
                .NotEmpty()
                    .WithMessage("Ein Status muss gewählt werden");

            RuleFor(m => m.KindId)
                .NotEmpty()
                    .WithMessage("Eine Art muss gewählt werden");
        }

        private bool CustomNumberDoesNotExistInSite(DeviationDataModel model)
        {
            var siteService = Singleton<IContainer>.Instance.Resolve<ISiteService>();
            var appendixService = Singleton<IContainer>.Instance.Resolve<IAppendixService>();

            if (model == null) return false;

            var allDeviations = new List<Core.Domain.Deviation.Deviation>();

            if (model.SiteId.HasValue)
            {
                var site = siteService.GetSiteById(model.SiteId.Value);

                if (site != null)
                    allDeviations.AddRange(
                        site.Appendices
                            .SelectMany(a => a.Deviations));

                if (site != null)
                    allDeviations.AddRange(
                        site.Deviations);
            }
            else if (model.AppendixId.HasValue)
            {
                var appendix = appendixService.GetAppendixById(model.AppendixId.Value);

                if (appendix != null && appendix.Site != null)
                    allDeviations.AddRange(
                        appendix.Site.Appendices
                            .SelectMany(a => a.Deviations));

                if (appendix != null && appendix.Site != null)
                    allDeviations.AddRange(
                        appendix.Site.Deviations);
            }

            var existingDeviation =
                allDeviations
                    .FirstOrDefault(d => d.CustomNumber == model.CustomNumber);

            if (existingDeviation != null && existingDeviation.Id == model.Id) return true;

            if (existingDeviation != null && existingDeviation.Id != model.Id) return false;

            if (existingDeviation == null) return true;

            return false;
        }
    }
}