@page "/Users"
@attribute [Authorize]
@using salesbook.Shared.Components.Layout
@using salesbook.Shared.Core.Entity
@using salesbook.Shared.Core.Interface
@inject IManageDataService ManageData

<HeaderLayout Title="Contatti"/>

<div class="container search-box">
    <div class="input-card clearButton">
        <MudTextField T="string?" Placeholder="Cerca..." Variant="Variant.Text" @bind-Value="TextToFilter" OnDebounceIntervalElapsed="FilterUsers" DebounceInterval="500"/>

        @if (!TextToFilter.IsNullOrEmpty())
        {
            <MudIconButton Class="closeIcon" Icon="@Icons.Material.Filled.Close" OnClick="() => FilterUsers(true)"/>
        }
    </div>
</div>

<div class="container users">
    @if (GroupedUserList?.Count > 0)
    {
        <Virtualize Items="FilteredGroupedUserList" Context="item">
            @if (item.ShowHeader)
            {
                <div class="letter-header">@item.HeaderLetter</div>
            }
            <UserCard User="item.User"/>
        </Virtualize>
    }
</div>

@code {
    private List<UserDisplayItem> GroupedUserList { get; set; } = [];
    private List<UserDisplayItem> FilteredGroupedUserList { get; set; } = [];
    private string? TextToFilter { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await LoadData();
            StateHasChanged();
        }
    }

    private async Task LoadData()
    {
        var users = await ManageData.GetTable<AnagClie>(x => x.FlagStato.Equals("A"));

        var sortedUsers = users
            .Where(u => !string.IsNullOrWhiteSpace(u.RagSoc))
            .OrderBy(u =>
            {
                var firstChar = char.ToUpper(u.RagSoc[0]);
                return char.IsLetter(firstChar) ? firstChar.ToString() : "ZZZ";
            })
            .ThenBy(u => u.RagSoc)
            .ToList();

        GroupedUserList = [];

        string? lastHeader = null;

        foreach (var user in sortedUsers)
        {
            var firstChar = char.ToUpper(user.RagSoc[0]);
            var currentLetter = char.IsLetter(firstChar) ? firstChar.ToString() : "#";

            var showHeader = currentLetter != lastHeader;
            lastHeader = currentLetter;

            GroupedUserList.Add(new UserDisplayItem
            {
                User = user,
                ShowHeader = showHeader,
                HeaderLetter = currentLetter
            });
        }

        FilterUsers(true);
    }

    private class UserDisplayItem
    {
        public required AnagClie User { get; set; }
        public bool ShowHeader { get; set; }
        public string? HeaderLetter { get; set; }
    }

    private void FilterUsers() => FilterUsers(false);

    private void FilterUsers(bool clearFilter)
    {
        if (clearFilter)
        {
            TextToFilter = null;
            FilteredGroupedUserList = GroupedUserList;
            StateHasChanged();
            return;
        }

        if (TextToFilter == null) return;

        FilteredGroupedUserList = GroupedUserList.FindAll(x =>
            x.User.RagSoc.Contains(TextToFilter, StringComparison.OrdinalIgnoreCase) ||
            x.User.Indirizzo.Contains(TextToFilter, StringComparison.OrdinalIgnoreCase) ||
            (x.User.Telefono != null && x.User.Telefono.Contains(TextToFilter, StringComparison.OrdinalIgnoreCase)) ||
            (x.User.EMail != null && x.User.EMail.Contains(TextToFilter, StringComparison.OrdinalIgnoreCase)) ||
            x.User.PartIva.Contains(TextToFilter, StringComparison.OrdinalIgnoreCase)
        );

        StateHasChanged();
    }

}