namespace MyOffice.Web.Infrastructure.Attributes;

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class DefaultFromBodyAttribute : Attribute
{
}

public class DefaultFromBodyBindingConvention : IActionModelConvention
{
	public void Apply(ActionModel action)
	{
		if (action == null)
		{
			throw new ArgumentNullException(nameof(action));
		}

		if (action.Controller.Attributes.Any(x => x is DefaultFromBodyAttribute))
		{			
			foreach (var parameter in action.Parameters)
			{
				if (parameter.Attributes.Any(x => x is FromQueryAttribute))
				{
					continue;
				}

				var paramType = parameter.ParameterInfo.ParameterType;
				var isSimpleType = paramType.IsPrimitive
									|| paramType.IsEnum
									|| paramType == typeof(string)
									|| paramType == typeof(int)
									|| paramType == typeof(Guid)
									|| paramType == typeof(DateTime)
									|| paramType == typeof(DateTime?)
									|| paramType == typeof(decimal);

				if (!isSimpleType)
				{
					parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
					parameter.BindingInfo.BindingSource = BindingSource.Body;
				}
			}
		}
	}
}
