using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace WebApplication1.Helpers {
	public static class HelpersExtension {
		public static MvcHtmlString AllValidationMessagesFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object attributs = null ) {
			var prop = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).PropertyName;
			var ms = htmlHelper.ViewData.ModelState;
			var dico = attributs as IDictionary<string, object>; // Dictionnary ou anonyme ? ? ?

			if( ms.ContainsKey( prop ) && ms[prop].Errors.Count > 1 ) { // Plus d'une erreur => concaténer
				var msgs = new StringBuilder();
				foreach( ModelError error in ms[prop].Errors ) {
					msgs.AppendLine( error.ErrorMessage );
				}
				if( dico != null )
					return htmlHelper.ValidationMessageFor( expression, // Réutiliser le helper classique
						msgs.ToString(), // Mais en lui faisant afficher la concaténation
						dico ); // Passer le dico dont les clés/valeurs seront utilisées pour créer des attributs HTML
				else
					return htmlHelper.ValidationMessageFor( expression, // Réutiliser le helper classique
						msgs.ToString(), // Mais en lui faisant afficher la concaténation
						attributs ); // Passer l'objet dont les propiétés/valeurs seront utilisées pour créer des attributs HTML
			}
			// Au plus une erreur => utiliser le helper classique :
			if( dico != null )
				return htmlHelper.ValidationMessageFor( expression, null, dico );
			else
				return htmlHelper.ValidationMessageFor( expression, null, attributs );
		}

		public static MvcHtmlString AllValidationMessagesToolTipFor<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object attributs = null ) {
			var prop = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).PropertyName;
			var ms = htmlHelper.ViewData.ModelState;

			if( !ms.ContainsKey( prop ) || ms[prop].Errors.Count < 1 )
				return MvcHtmlString.Empty;

			IDictionary<string, object> dico = attributs as IDictionary<string, object>;
			if( dico == null && attributs != null ) {
				dico = HtmlHelper.ObjectToDictionary( attributs );
			}
			else {
				dico = new Dictionary<string, object>(2);
			}
			if( dico.ContainsKey( "class" ) ) {
				dico["class"] = $"{dico["class"]} ValidationMessagesToolTip";
      }
			else {
				dico["class"] = "ValidationMessagesToolTip";
			}

			var msgs = new StringBuilder();
			foreach( ModelError error in ms[prop].Errors ) {
				msgs.AppendLine( error.ErrorMessage );
			}
			msgs.Replace( "\"", "\\\"" );
			if( dico.ContainsKey( "title" ) )
				dico["title"] = string.Format( "{0}\n{1}", dico["title"], msgs );
			else
				dico["title"] = msgs;

			var html = new StringBuilder();
			html.AppendFormat( "<{0}", HtmlHelper.ValidationMessageElement );
			foreach( var attr in dico ) {
				html.AppendFormat( " {0}=\"{1}\"", attr.Key, attr.Value.ToString().Replace( "\"", "\\\"" ) );
			}
			html.AppendFormat( ">*</{0}>", HtmlHelper.ValidationMessageElement );
			return new MvcHtmlString( html.ToString() );
		}
	}
}
