using HRD.AppLogger;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace HRD.WebApi.Helpers
{
    public class HttpErrorDetails : ValidationProblemDetails
    {
        public HttpErrorDetails()
        {
        }

        public HttpErrorDetails(ActionContext context)
        {
            Title = "Invalid arguments to the API";
            Detail = "The inputs supplied to the API are invalid";
            Status = StatusCodes.Status400BadRequest;
            Type = context.HttpContext.TraceIdentifier;
            URI = context.HttpContext.Request.Path.ToUriComponent();

            ConstructErrorMessages(context);
        }

        public string URI { get; set; }

        public string ToJsonString()
        {
            return JsonConvert.Serialize(this);
        }

        private void ConstructErrorMessages(ActionContext context)
        {
            foreach (var keyModelStatePair in context.ModelState)
            {
                var key = keyModelStatePair.Key;
                var errors = keyModelStatePair.Value.Errors;
                if (errors != null && errors.Count > 0)
                {
                    ILoggerManager logger = new LoggerManager();
                    if (errors.Count == 1)
                    {
                        var errorMessage = GetErrorMessage(errors[0]);
                        base.Errors.Add(key, new[] { errorMessage });
                        logger.LogError(errorMessage, null, URI);
                        Detail = errorMessage;
                    }
                    else
                    {
                        var errorMessages = new string[errors.Count];
                        for (var i = 0; i < errors.Count; i++)
                        {
                            errorMessages[i] = GetErrorMessage(errors[i]);
                            logger.LogError(errorMessages[i], null, URI);
                            if (i == 0) { Detail = errorMessages[i]; }
                        }
                        base.Errors.Add(key, errorMessages);
                    }
                }
            }
        }

        private string GetErrorMessage(ModelError error)
        {
            return string.IsNullOrEmpty(error.ErrorMessage) ?
                "The input was not valid." : error.ErrorMessage;
        }
    }
}