using FluentValidation.Results;

namespace CMSMicroservice.Application.Common.Exceptions;

public class ValidationException : Exception
{
    public ValidationException()
        : base("One or more validation failures have occurred.")
    {
        Errors = new Dictionary<string, string[]>();
    }

    public ValidationException(IEnumerable<ValidationFailure> failures)
        : base(BuildMessage(failures, out var errors))
    {
        Errors = errors;
    }

    public IDictionary<string, string[]> Errors { get; }

    private static string BuildMessage(IEnumerable<ValidationFailure> failures, out IDictionary<string, string[]> errors)
    {
        var list = failures?.Where(f => !string.IsNullOrWhiteSpace(f.ErrorMessage)).ToList() ?? new List<ValidationFailure>();

        errors = list
            .GroupBy(e => e.PropertyName, e => e.ErrorMessage)
            .ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray());

        var items = list
            .Select(f => string.IsNullOrWhiteSpace(f.PropertyName)
                ? f.ErrorMessage
                : $"{f.PropertyName}: {f.ErrorMessage}")
            .Where(s => !string.IsNullOrWhiteSpace(s))
            .ToArray();

        return items.Length > 0
            ? string.Join(" | ", items)
            : "One or more validation failures have occurred.";
    }
}
