using DiplomovaPrace.Contracts.Customer.Addresses;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace DiplomovaPrace.Contracts.Customer.Orders.InputModels
{
	public class OrderIM : IValidatableObject
	{
		public int? UserID { get; set; } // for registered customers

		[Required(ErrorMessage = "InvoicingAddress is required.")]
		public AddressDto InvoicingAddress { get; set; }

		public DeliveryAddressDto DeliveryAddress { get; set; }

		[Required(ErrorMessage = "OrderItems are required.")]
		public List<OrderItemIM> OrderItems { get; set; } = new();

		public PasswordIM Password { get; set; }

		[Required(ErrorMessage = "DeliveryTypeID is required.")]
		public int DeliveryTypeID { get; set; }

		[Required(ErrorMessage = "PaymentTypeID is required.")]
		public int PaymentTypeID { get; set; }
		
		public class PasswordIM : IValidatableObject
		{
			public string Password { get; set; }

			public string ConfirmPassword { get; set; }

			public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
			{
				// checkovat pouze jestli je password null ne jestly je whitespace
				if (!string.IsNullOrWhiteSpace(Password) || !string.IsNullOrWhiteSpace(ConfirmPassword))
				{
					if (Password.Length < 8)
					{
						yield return new ValidationResult("Must be at least 8 characters long!", new[] { nameof(Password) });
					}

					if (ConfirmPassword.Length < 8)
					{
						yield return new ValidationResult("Must be at least 8 characters long!", new[] { nameof(ConfirmPassword) });
					}

					if (!Password.Equals(ConfirmPassword))
					{
						yield return new ValidationResult("ConfirmPassword must be same as Password!", new[] { nameof(ConfirmPassword) });
					}
				}
			}
		}

		public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
		{
			IEnumerable<ValidationResult> validationResult;

			if (InvoicingAddress.ID is null)
			{
				validationResult = InvoicingAddress.Validate(validationContext);

				//TODO: Ověřit, že zadaný email nepatří k již registrovanému účtu

				foreach (var validationResultItem in validationResult)
				{
					yield return validationResultItem;
				}
			}
			else
			{
				//TODO: TV Oveřit že InvoicingAddress.ID patří k danemu emailu
				// Možná ověřovat i fakt, že i zde již registrovaný uživatele nezadá email jiného registrovaného účtu
			}

			if (DeliveryAddress is not null)
			{
				if (DeliveryAddress.ID is null)
				{
					validationResult = DeliveryAddress.Validate(validationContext);

					foreach (var validationResultItem in validationResult)
					{
						yield return validationResultItem;
					}
				}
				else
				{
					//TODO: TV Oveřit že DeliveryAddress.ID patří k danému emailu
				}
			}

			if (OrderItems is null || OrderItems.Count == 0)
			{
				yield return new ValidationResult("OrderItems must not be empty!", new[] { nameof(OrderItems) });
			}

			if (Password is not null)
			{
				if (!string.IsNullOrWhiteSpace(Password.Password) || !string.IsNullOrWhiteSpace(Password.ConfirmPassword))
				{
					validationResult = Password.Validate(validationContext);

					foreach (var validationResultItem in validationResult)
					{
						yield return validationResultItem;
					}

					//TODO: Ověřit, že zadaný email nepatří k již registrovanému účtu
				}
			}
		}
	}
}
