using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Kit.Helpers
{
    public static class MicrosoftAspNetCoreMvcViewFeaturesExtension
    {
        public static IHtmlContent ValidationClassFor<TModel, TResult>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TResult>> expression, string classNameValid = "is-valid", string classNameInvalid = "is-invalid")
        {
            ArgumentNullException.ThrowIfNull(expression);
            string memberName = GetMemberName(expression);
            var state = htmlHelper.ViewData.ModelState[memberName];

            var validationState = state?.ValidationState ?? ModelValidationState.Unvalidated;

            switch (validationState)
            {
                case ModelValidationState.Invalid: return htmlHelper.Raw(classNameInvalid);
                case ModelValidationState.Valid: return htmlHelper.Raw(classNameValid);
                default: return htmlHelper.Raw(string.Empty);
            }
        }

        private static string GetMemberName<TModel, TResult>(Expression<Func<TModel, TResult>> expression)
        {
            if (expression.Body is MemberExpression memberExpression)
            {
                // Если выражение представляет доступ к полю или свойству
                return memberExpression.Member.Name;
            }
            else if (expression.Body is UnaryExpression unaryExpression && unaryExpression.Operand is MemberExpression unaryMemberExpression)
            {
                // Если выражение представляет собой унарную операцию (например, приведение типа)
                return unaryMemberExpression.Member.Name;
            }

            throw new ArgumentException("Выражение должно представлять доступ к полю или свойству.", nameof(expression));
        }
    }
}