using FluentValidation;
using GreenTree.Maschinenbestellungen.Core.Helper;
using GreenTree.Maschinenbestellungen.Domain.Model;
using GreenTree.Maschinenbestellungen.Services.Authorization;
using GreenTree.Maschinenbestellungen.Web.Models.Account;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GreenTree.Maschinenbestellungen.Web.Validators
{
    public class LoginValidator : AbstractValidator<LoginModel>
	{
		#region DI fields

		// The global DbContext
		private readonly OrderDbContext _eRPDbContext;

		// The global user helper
		private readonly IUserHelper _userHelper;

		// The global administration options
		private readonly AdministrationOptions _administrationOptions;

		#endregion

		#region Ctor

		/// <summary>
		/// Initializes a new instance of the LoginValidator class
		/// </summary>
		/// <param name="eRPDbContext">Global DbContext.</param>
		/// <param name="userHelper">Global user helper.</param>
		public LoginValidator(
			OrderDbContext eRPDbContext,
			IUserHelper userHelper,
			AdministrationOptions administrationOptions)
		{
			_eRPDbContext = eRPDbContext;
			_userHelper = userHelper;
			_administrationOptions = administrationOptions;

			RuleFor(x => x.Username)
				.NotEmpty()
				.WithMessage("Benutzername erforderlich.")
				.Custom((a, context) =>
				{
					if (a == _administrationOptions.Administrator)
						return;

					if (!_eRPDbContext.Users.Any(u => u.Accountname == a || u.MailAddress == a))
					{
						context.AddFailure("Benutzername nicht gefunden.");
						return;
					}
				});

			RuleFor(x => x.Password)
				.NotEmpty()
				.WithMessage("Passwort erforderlich.")
				.Custom((p, context) =>
				{
					if (String.IsNullOrEmpty(p))
						return;

					var model = context.InstanceToValidate as LoginModel;

					if (model == null)
					{
						context.AddFailure("Unbekannter Fehler.");
						return;
					}

					if (model.Username == administrationOptions.Administrator)
					{
						if (_userHelper.HashString(p, false) == _administrationOptions.Password)
							return;
						else
                        {
							context.AddFailure("Kennwort falsch.");
							return;
						}
					}

					var user = _eRPDbContext.Users
						.FirstOrDefault(u => u.Accountname == model.Username || u.MailAddress == model.Username);

					if (user == null)
					{
						context.AddFailure("Unbekannter Fehler.");
						return;
					}

					if (user.Password != _userHelper.HashString(p, true))
						context.AddFailure("Kennwort falsch.");

					return;
				});
		}

		#endregion
	}
}
