@page "/GlobalList"
@rendermode InteractiveServer

@using Microsoft.AspNetCore.Authorization
@using CouchLog.Data
@using Microsoft.AspNetCore.Identity
@using Microsoft.EntityFrameworkCore
@using CouchLog.Components.Pages.GlobalList.Dialogs

@inject ApplicationDbContext CouchLogDb
@inject UserManager<ApplicationUser> UserManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IDialogService DialogService
@inject ISnackbar Snackbar

@attribute [Authorize]

<PageTitle>GlobalList</PageTitle>
@*
TODO: Add Paging
TODO: Add only reload for the pages
TODO: Make Search work
*@

<MudContainer MaxWidth="MaxWidth.False">
    @*Top of the Page*@
    <MudContainer>
        <MudStack Row="true" AlignItems="AlignItems.Center">
            @*Page Title*@
            <MudText Typo="Typo.h3" Style="font-weight: bold;">Global List</MudText>
            
            @*Spacer*@
            <MudSpacer />

            @*Button for adding GlobalEntity*@
            <MudTooltip Text="Add GlobalEntity">
                <MudFab StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary" OnClick="OpenAddNewGlobalEntityDialog"/>
            </MudTooltip>
        </MudStack>
    </MudContainer>
    
    <br/>
    
    <MudContainer>
        <MudPaper Class="pa-2" Elevation="1">
            <MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
                <MudTextField @bind-Value="_searchString"
                              Placeholder="Search..."
                              Adornment="Adornment.Start"
                              AdornmentIcon="@Icons.Material.Filled.Search"
                              Immediate="true"
                              Variant="Variant.Outlined"
                              Margin="Margin.Dense"
                              Style="max-width: 300px;"/>
                <MudTooltip Text="More filters">
                    <MudIconButton Icon="@(_showFilters
                                             ? Icons.Material.Filled.ExpandLess
                                             : Icons.Material.Filled.FilterList)"
                                   OnClick="@(() => _showFilters = !_showFilters)"
                                   Color="Color.Default" />
                </MudTooltip>
            </MudStack>
            <MudCollapse Expanded="_showFilters">
                <MudSwitch @bind-Value="_showAlreadyAddedEntities" Color="Color.Primary">
                    Show already added Entities
                </MudSwitch>
            </MudCollapse>
        </MudPaper>
    </MudContainer>
    
    <br/>
    
    <MudContainer MaxWidth="MaxWidth.False">
        <MudGrid Spacing="6" Justify="Justify.Center">
            @foreach (var globalEntity in _globalEntities)
            {
                if (!globalEntity.IsPrivate || (globalEntity.IsPrivate && (globalEntity.CreatorId == _appUser?.Id)))
                {
                    if (_showAlreadyAddedEntities || !_userPrivateEntityIds.Contains(globalEntity.Id))
                    {
                        <MudItem xs="12" sm="6" md="4" lg="3" xl="2">
                            <MudCard>
                                <MudPaper Elevation="0">
                                    <MudCardMedia Image="@globalEntity.PicturePath" Height="400" Style="object-fit: contain;"/>
                                </MudPaper>
                                <MudCardContent>
                                    <MudText Typo="Typo.h5">@globalEntity.Title</MudText>
                                </MudCardContent>
                                <MudCardActions>
                                    <MudTooltip Text="Add to shared List">
                                        <MudIconButton Icon="@Icons.Material.Rounded.People" Color="Color.Primary" OnClick="AddGlobalEntityToSharedList"/>
                                    </MudTooltip>
                                    <MudSpacer/>
                                    @if (_userPrivateEntityIds.Contains(globalEntity.Id))
                                    {
                                        <MudTooltip Text="Already added to Private List">
                                            <MudIconButton Icon="@Icons.Material.Rounded.Check" Color="Color.Primary"/>
                                        </MudTooltip>
                                    }
                                    else
                                    {
                                        <MudTooltip Text="Add to private List">
                                            <MudIconButton Icon="@Icons.Material.Rounded.Lock" Color="Color.Primary" OnClick="() => AddGlobalEntityToPrivateList(globalEntity)"/>
                                        </MudTooltip>
                                    }
                                </MudCardActions>
                            </MudCard>
                        </MudItem>
                    }
                }
            }
        </MudGrid>
    </MudContainer>
</MudContainer>

@code
{
    //Search
    private string _searchString;
    
    //Filter Variables
    private bool _showFilters;
    private bool _showAlreadyAddedEntities = false;
    
    private ApplicationUser? _appUser;
    private List<GlobalEntity> _globalEntities = [];
    private HashSet<int> _userPrivateEntityIds = [];
    
    protected override async Task OnInitializedAsync()
    {
        _globalEntities = await CouchLogDb.GlobalEntities.OrderByDescending(entity => entity.CreationTime).ToListAsync();
        
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        _appUser = await UserManager.GetUserAsync(authState.User);

        if (_appUser is null)
        {
            Snackbar.Add("Not authenticated.", Severity.Error);
            return;
        }

        _userPrivateEntityIds = await CouchLogDb.PrivateEntities
            .Where(entity => entity.UserId == _appUser.Id)
            .Select(p => p.GlobalEntityId)
            .ToHashSetAsync();
    }
    
    
    private async Task OpenAddNewGlobalEntityDialog()
    {
        var dialog = await DialogService.ShowAsync<AddNewGlobalEntityDialog>("Add new Global Entity");
    }

    private async Task<bool> IsFilterValid(GlobalEntity globalEntity)
    {
        if (!_showAlreadyAddedEntities && await IsInPrivateList(globalEntity.Id))
        {
            return false;
        }

        return true;
    }
    
    private async Task AddGlobalEntityToPrivateList(GlobalEntity globalEntity)
    {
        if(_appUser is null) { Snackbar.Add("Not logged in!", Severity.Error); return;}
        
        if (!await IsInPrivateList(globalEntity.Id))
        {
            PrivateEntity privateEntity = new()
            {
                UserId = _appUser.Id,
                CreationTime = DateTime.Now,
                GlobalEntityId = globalEntity.Id,
                UserWatchStatusId = 1,
            };

            CouchLogDb.PrivateEntities.Add(privateEntity);
            await CouchLogDb.SaveChangesAsync();
            
            StateHasChanged();
            Snackbar.Add("Added Entity to private List", Severity.Success);
        }
        else
        {
            Snackbar.Add("Entity already in private List!", Severity.Warning);
        }
    }

    private async Task<bool> IsInPrivateList(int globalEntityId)
    {
        if (_appUser is null) return false;
        
        return await CouchLogDb.PrivateEntities.Where(entity => entity.UserId == _appUser.Id).AnyAsync(entity => entity.GlobalEntityId == globalEntityId);
    }
    
    private void AddGlobalEntityToSharedList()
    {
        Snackbar.Add("Feature not implemented yet!", Severity.Error);
    }
}