using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace AsbCloudApp.Data
{
    /// <summary>
    /// Плановое значение и максимально допустимое ограничение
    /// </summary>
    public class PlanLimitDto
    {
        /// <summary>
        /// План
        /// </summary>
        [Required]
        public double Plan { get; set; }

        /// <summary>
        /// Максимальное ограничение
        /// </summary>
        [Required]
        public double LimitMax { get; set; }

        /// <summary>
        /// Валидация
        /// </summary>
        /// <param name="commonRange">Общий диапазон для плана и ограничения</param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public virtual IEnumerable<ValidationResult> Validate((double GE, double LE) commonRange, string paramName)
            => Validate(commonRange, commonRange, paramName);

        /// <summary>
        /// Валидация
        /// </summary>
        /// <param name="planRange"></param>
        /// <param name="limitMaxRange"></param>
        /// <param name="paramName">Название параметра для которого задается план и ограничение</param>
        /// <returns></returns>
        public virtual IEnumerable<ValidationResult> Validate((double GE, double LE) planRange, (double GE, double LE) limitMaxRange, string paramName)
        {
            if (Plan < planRange.GE || Plan > planRange.LE)
                yield return new ValidationResult($"{paramName} плановое значение должно быть в диапазоне [{planRange.GE}; {planRange.LE}].");

            if (Plan < planRange.GE || Plan > planRange.LE)
                yield return new ValidationResult($"{paramName} ограничивающее значение должно быть в диапазоне [{limitMaxRange.GE}; {limitMaxRange.LE}].");
        }
    }

    /// <summary>
    /// Реализация RangeAttribute для PlanLimitDto
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
    AllowMultiple = false)]
    public class RangePlanLimitAttribute : ValidationAttribute
    {
        private readonly double minimum;
        private readonly double maximum;

        /// <summary>
        /// Реализация RangeAttribute для PlanLimitDto
        /// </summary>
        /// <param name="minimum"></param>
        /// <param name="maximum"></param>
        public RangePlanLimitAttribute(double minimum, double maximum)
        {
            this.minimum = minimum;
            this.maximum = maximum;
        }

        /// <inheritdoc/>
        public override bool IsValid(object? value)
        {
            try
            {
                if(value is PlanLimitDto dto)
                {
                    var isPlanValid = dto.Plan <= maximum && dto.Plan >= minimum;
                    var isLimitMaxValid = dto.LimitMax <= maximum && dto.LimitMax >= minimum;
                    return isPlanValid && isLimitMaxValid;
                }
            }catch{}
            return false;
        }
    }
}