namespace Utilitarios.APINet.Atributos
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using UtilitariosNet.Recursos;

    public class FechaSuperiorAttribute : ValidationAttribute
    {
        /// <summary>
        /// Propiedad a probar
        /// </summary>
        private readonly string fechaInicial;

        /// <summary>
        /// Indica si se permiten fechas iguales
        /// </summary>
        private readonly bool permitirFechasIguales;

        /// <summary>
        /// Constructor de la clase
        /// </summary>
        /// <param name="fechaInicial">Propiedad a validar</param>
        /// <param name="permitirFechasIguales">Indica si se permiten fechas iguales</param>
        public FechaSuperiorAttribute(string fechaInicial, bool permitirFechasIguales = false)
        {
            this.fechaInicial = fechaInicial;
            this.permitirFechasIguales = permitirFechasIguales;
        }

        /// <summary>
        /// Metodo que valida si una fecha es mayor que la otra
        /// </summary>
        /// <param name="value">Valor de la propiedad a la cual se aplica el atributo.</param>
        /// <param name="validationContext">Contexto de validacion</param>
        /// <returns>
        /// True si la fecha de referencia es mayor a la fecha a verificar. De lo contrario False
        /// </returns>
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.fechaInicial);

            if (propertyTestedInfo == null)
            {
                return new ValidationResult(string.Format(RecursosUtilitarios.PropiedadDesconocida, this.fechaInicial));
            }

            var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);

            if (value == null || !(value is DateTime))
            {
                return ValidationResult.Success;
            }

            if (propertyTestedValue == null || !(propertyTestedValue is DateTime))
            {
                return ValidationResult.Success;
            }

            if ((DateTime)value >= (DateTime)propertyTestedValue)
            {
                if (this.permitirFechasIguales)
                {
                    return ValidationResult.Success;
                }
                if ((DateTime)value > (DateTime)propertyTestedValue)
                {
                    return ValidationResult.Success;
                }
            }

            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
    }
}