using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Primitives;

namespace JSMR.UI.Blazor.Filters;

public class QueryParameters : Dictionary<string, string?>
{
    public QueryParameters()
    {

    }
    public QueryParameters(IEnumerable<KeyValuePair<string, StringValues>> items)
    {
        foreach (var kv in items)
        {
            this[kv.Key] = kv.Value.ToString();
        }
    }

    public static QueryParameters FromQueryString(string query)
        => new(QueryHelpers.ParseQuery(query));

    public void Set(string key, string? value, bool includeWhenEmpty = false)
    {
        if (includeWhenEmpty || !string.IsNullOrWhiteSpace(value))
            this[key] = value;
    }

    public bool Has(string key) => ContainsKey(key);

    public string? GetValue(string key) => TryGetValue(key, out var value) ? value!.ToString() : null;
    public string[] GetValues(string key) => GetValue(key)?.Split(',', StringSplitOptions.RemoveEmptyEntries) ?? [];

    public int GetInteger(string key, int defaultValue)
        => TryGetValue(key, out var value) && int.TryParse(value, out int intValue) ? intValue : defaultValue;

    public int[] GetIntegers(string key) => [.. GetValues(key).Select(int.Parse)];

    public T? GetEnum<T>(string key) where T : struct, Enum
            => TryGetValue(key, out var value) && Enum.TryParse<T>(value!, true, out var enumValue) ? enumValue : null;

    public TEnum[] GetEnums<TEnum>(string key) where TEnum : struct, Enum
            => GetValues(key).Select(value =>
                Enum.TryParse<TEnum>(value, true, out var enumValue)
                    ? enumValue
                    : (TEnum?)null).Where(e => e is not null).Select(e => e!.Value).ToArray()
               ?? [];

    public DateOnly? GetDate(string key, string? format = "yyyy-MM-dd")
        => DateOnly.TryParseExact(GetValue(key), format, out var date) ? date : null;
}