using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Primitives;
using System.Web;

namespace Insight.Web.Extensions;

public static class NavigationManagerExtensions
{
    public static Dictionary<string, StringValues> GetQueryString(this NavigationManager navigationManager)
    {
        var uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
        if (uri is null) return new Dictionary<string, StringValues>();

        return QueryHelpers.ParseQuery(uri.Query);
    }

    public static void ChangeQueryStringValue(this NavigationManager navigationManager, string key, string? value = null)
    {
        var queryString = GetQueryString(navigationManager);

        if (queryString.ContainsKey(key))
        {
            if (queryString[key] == value) return;
            queryString[key] = value;
        }
        else
        {
            if (value is null) return;
            queryString.Add(key, value);
        }

        var uri = ReplaceQueryString(navigationManager.Uri, queryString);
        navigationManager.NavigateTo(uri);
    }

    private static void ChangeQueryString(this NavigationManager navigationManager, Dictionary<string, StringValues> queryStrings)
    {
        var uri = ReplaceQueryString(navigationManager.Uri, queryStrings);
        navigationManager.NavigateTo(uri);
    }

    private static string ReplaceQueryString(string uri, Dictionary<string, StringValues> queryString)
    {
        string url = uri;

        foreach (var key in queryString.Keys)
        {
            url = RemoveQueryStringByKey(url, key);
        }

        var query = new Dictionary<string, string>();
        foreach (var keys in queryString.Where(x => string.IsNullOrWhiteSpace(x.Value) is false))
        {
            query.Add(keys.Key, keys.Value.ToString());
        }

        return QueryHelpers.AddQueryString(url, query);
    }

    public static string ReplaceQueryStrings(string uri, Dictionary<string, string?> parameters)
    {
        string url = uri;

        foreach (var key in parameters.Keys)
        {
            url = RemoveQueryStringByKey(url, key);
        }

        return QueryHelpers.AddQueryString(url, parameters);
    }

    private static string RemoveQueryStringByKey(string url, string key)
    {
        var uri = new Uri(url);

        // this gets all the query string key value pairs as a collection
        var newQueryString = HttpUtility.ParseQueryString(uri.Query);

        // this removes the key if exists
        newQueryString.Remove(key);

        // this gets the page path from root without QueryString
        string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);

        return newQueryString.Count > 0
            ? string.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
            : pagePathWithoutQueryString;
    }
}