@using System;
@using Sandbox;
@using Sandbox.UI;
@using System.Threading
@namespace Sandbox.UI
@inherits Panel

@if ( Result == null )
{
    return;
}

<root class="packagefilter">

    <div class="left">

    @foreach ( var facet in Result.Facets )
    {
        filterFacets.TryGetValue( facet.Name, out var value );

        <PackageFilterFacet Facet="@facet" Value="@value" OnChange="@OnFacetChanged"></PackageFilterFacet>
    }

    </div>

    <div class="right">
        <TextEntry placeholder="Search.." OnTextEdited=@OnSearchEdited></TextEntry>
        <PackageFilterOrder Orders="@Result.Orders" Value="@filterOrder" OnChange="@OnOrderChanged"></PackageFilterOrder>
    </div>

</root>

@code
{

	[Parameter] public string Query { get; set; }
	[Parameter] public string SearchString { get; set; }
	[Parameter] public Package.FindResult Result { get; set; }
	[Parameter] public Action<string> OnChange { get; set; }

	List<string> filterTypes;
	List<string> tags;
	Dictionary<string, string> filterFacets;
    string filterOrder;

    RealTimeUntil timeUntilRunDebouncedAction;
    Action debouncedAction;

    protected override void OnParametersSet()
    {
        BuildFilter( Query );
    }

    void BuildFilter( string query )
    {
        string[] parts = query.Split(' ');
        filterTypes = parts.Where(x => x.StartsWith("type:")).Select(x => x.Substring(5)).ToList();
        filterOrder = parts.Where(x => x.StartsWith("sort:")).Select(x => x.Substring(5)).FirstOrDefault();
        tags = parts.Where(x => x.StartsWith("+" )).Select(x => x.Substring(1)).ToList();
		filterFacets = parts.Where( x => x.Contains( ":" ) )
                                        .Select(x => x.Split( ":" ))
                                        .Where( x => x[0] != "type" )
                                        .Where( x => x[0] != "sort" )
                                        .Where( x => x.Length == 2 )
                                        .ToDictionary( x => x[0], x => x[1]) ;
    }

    string BuildQuery()
    {
        var q = "";

        foreach (var t in filterTypes)
            q += $" type:{t}";        

        foreach (var t in filterFacets)
            q += $" {t.Key}:{t.Value}";

        if ( !string.IsNullOrWhiteSpace(filterOrder) )
            q += $" sort:{filterOrder}";

		foreach(var t in tags)
			q += $" +{t}";

        if (!string.IsNullOrWhiteSpace(SearchString))
        {
            q += $" {SearchString}";
        }

        Log.Info( q );

        return q;
    }

    void OnSearchEdited( string value )
    {
        debouncedAction = () =>
        {
            SearchString = value;
            OnChange?.Invoke(BuildQuery());
        };

        timeUntilRunDebouncedAction = 0.5f;
    }

    void OnFacetChanged( Package.Facet facet, string value )
    {
        if (string.IsNullOrEmpty(value))
            filterFacets.Remove(facet.Name);
        else
            filterFacets[facet.Name] = value;

        OnChange?.Invoke( BuildQuery() );
    }

    void OnOrderChanged( string value )
    {
        filterOrder = value;
        OnChange?.Invoke( BuildQuery() );
    }

    public override void Tick()
    {
        if ( debouncedAction != null && timeUntilRunDebouncedAction <= 0.0f )
        {
            debouncedAction();
            debouncedAction = null;
        }
    }
}
