using System;
using System.ComponentModel.DataAnnotations;

namespace AsbCloudApp.ValidationAttributes
{
    /// <summary>
    /// Атрибут валидации даты-времени
    /// </summary>
    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
    public class DateValidationAttribute : ValidationAttribute
    {
        private DateTime? gtDate;

        /// <summary>
        /// null разрешен
        /// </summary>
        public bool AllowNull { get; set; } = true;

        /// <summary>
        /// Разрешена только дат.
        /// При наличии времени в DateTime инвалидирует.
        /// При наличии UTC тоже инвалидирует.
        /// </summary>
        public bool IsDateOnly { get; set; } = false;

        /// <summary>
        /// Допустима дата-время в UTC
        /// </summary>
        public bool AllowUtc { get; set; } = true;

        /// <summary>
        /// Дата больше которой должно быть проверяемое значение.
        /// Формат строки - любой поддерживаемый DateTime.Parse.
        /// Желательно использовать ISO 8601 формат
        /// </summary>
        public string? GtDate { 
            get => gtDate.ToString(); 
            set
            {
                if(value is null)                
                    gtDate = null;                
                else                
                    gtDate = DateTime.Parse(value);                
            }
        }

        /// <summary>
        /// Проверка значения
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool IsValid(object? value)
        {
            if (value is null)
                return AllowNull;

            if (value is not DateTime dateTime)
                return false;

            if (IsDateOnly)
            {
                if (dateTime.Hour > 0 ||
                    dateTime.Minute > 0 ||
                    dateTime.Second > 0 ||
                    dateTime.Millisecond > 0 ||
                    dateTime.Kind == DateTimeKind.Utc)
                    return false;
            }

            if (!AllowUtc && dateTime.Kind == DateTimeKind.Utc)
                return false;

            if (gtDate.HasValue && dateTime <= gtDate)
                return false;

            return true;
        }

    }
}