UI/FeaturesPanel.razor
@using Sandbox;
@using Sandbox.UI;
@using System;
@using HC3.UI;

@inherits SingletonWindow<FeaturesPanel>
@namespace HC3

<root class="column gap">
    <div class="row groups no-shrink">
        <button class="@(CurrentGroup == "Decoration" ? "selected" : "") square-button" tooltip="Decorations" onclick=@(() => SetGroup("Decoration"))>
            <img src="textures/hud/tree.png" />
        </button>
        <button class="@(CurrentGroup == "Furniture" ? "selected" : "") square-button" tooltip="Path Furniture" onclick=@(() => SetGroup("Furniture"))>
            <img src="textures/hud/street.png" />
        </button>

        <div class="grow" />

        <div class="tags">
            @foreach (var tag in AvailableTags)
            {
                <tag class="@(EnabledTags.Contains(tag) ? "" : "off")"
                     tooltip="@tag.ToTitleCase()"
                     onclick=@(() => ToggleTag(tag))>
                    @GetTagIcon(tag)
                </tag>
            }
        </div>
    </div>

    <div class="row grow">
        <column class="tree">
            @foreach ( var group in IPlacementObject.GetAllPrefabs( CurrentGroup )
                                                    .Where( x => !EnabledTags.Any() || (x.GetTags()?.Intersect( EnabledTags ).Any() ?? false ) )
                                                    .GroupBy( x => x.Group.SecondaryGroup )
                                                    .OrderBy( g => g.Key ) )
            {
                var isSelected = group.Key == CurrentSecondaryGroup;
                <button class="tree-root @(isSelected ? "selected" : "")"
                        onclick=@(() => SetSecondaryGroup( group.Key ))> @(group.Key) (@group.Count()) </button>
            }
        </column>

        <div class="window-container">
            <div class="items">
                @foreach ( var item in Items.OrderBy( x => x.GetOrder() ) )
                {
                    <CatalogItemPanel Item=@item />
                }
            </div>
        </div>
    </div>
</root>

@code
{
    public override string Title => $"{CurrentGroup} Catalog";
    public override string Icon => "bug";

    public string CurrentGroup { get; set; } = "Decoration";

    public string? CurrentSecondaryGroup { get; set; } = null;

    public IEnumerable<IPlacementObject> AllPrefabs =>
        IPlacementObject.GetAllPrefabs(CurrentGroup);

    public IEnumerable<string> AvailableTags =>
        AllPrefabs
            .SelectMany(x => x.GetTags() ?? Enumerable.Empty<string>())
            .Distinct()
            .OrderBy(x => x);

    public IEnumerable<IPlacementObject> Items =>
        AllPrefabs
            .Where(x => string.IsNullOrEmpty(CurrentSecondaryGroup) || x.Group.SecondaryGroup == CurrentSecondaryGroup)
            .Where(x => !EnabledTags.Any() || (x.GetTags()?.Intersect(EnabledTags).Any() ?? false));


    public List<string> EnabledTags { get; set; } = new();

    // TODO: move this to some kind of visual manager that we can edit / add new stuff to
    private string GetTagIcon(string tag) => tag switch
    {
        "castle" => "castle",
        "primitive" => "cabin",
        "nature" => "park",
        "modern" => "apartment",
        "zoo" => "pets",
        _ => tag
    };

    public void ToggleTag( string tag )
    {
        if ( EnabledTags.Contains( tag ) )
            EnabledTags.Remove( tag );
        else
            EnabledTags.Add( tag );

        // If we switched a tag, our selected group might not have any items left, so we reset the secondary group
        if ( !Items.Any() )
            CurrentSecondaryGroup = null;

        StateHasChanged();
    }

    public void SetGroup( string group )
    {
        EnabledTags.Clear();
        CurrentGroup = group;
        CurrentSecondaryGroup = null; // reset sub-group on group switch

        StateHasChanged();
    }

    public void SetSecondaryGroup( string group )
    {
        CurrentSecondaryGroup = group;
        StateHasChanged();
    }

    protected override int BuildHash() => System.HashCode.Combine( base.BuildHash(), BuildingPlacer.Instance?.IsDestroying );

    public override void Tick()
    {
        SetClass( "visible", IsVisible );
    }
}