@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using RobotNet.MapShares.Models

@inject IConfiguration Configuration
@inject IJSRuntime JSRuntime
@inject IHttpClientFactory HttpClientFactory

<div class="data-preview">
    <div class="d-flex" style="height: fit-content;">
        <MudTextField Class="mt-1 ms-2 d-flex justify-content-center" T="string" Value="FilterLog" Adornment="Adornment.End" ValueChanged="OnSearch" AdornmentIcon="@Icons.Material.Filled.Search"
                      IconSize="Size.Medium" Variant="Variant.Text" Margin="Margin.Dense" AdornmentColor="Color.Secondary" Label="Search" />
        <MudSpacer />
        <div class="m-1 d-flex flex-row">
            <MudDatePicker Class="mx-4" Label="Date" Date="DateLog" DateChanged="OnDateChanged" MaxDate="DateTime.Today" Variant="Variant.Text" Color="Color.Primary"
                           ShowToolbar="false" Margin="Margin.Dense" AdornmentColor="Color.Primary" />
            <MudTooltip Text="Refresh">
                <MudFab Class="mx-4 mt-2" StartIcon="@Icons.Material.Filled.Refresh" Color="Color.Primary" Size="Size.Small" OnClick="@(async() => await LoadLogs(false))" />
            </MudTooltip>
        </div>
    </div>
    <div class="content">
        <div class="log-container" @ref="LogContainerRef">
            @foreach (var log in SearchLogs)
            {
                <div class="log">
                    <span class="log-head">
                        @log.Time <span class="log-level">@log.Level</span>
                    </span>
                    <span class="@log.ColorClass">@log.Message</span>
                    @if (log.HasException)
                    {
                        <br />
                        <pre class="log-exception">
                            @log.Exception
                                </pre>
                    }
                </div>
            }
        </div>
    </div>

    <MudOverlay @bind-Visible="IsLoading" DarkBackground="true" Absolute="true">
        <MudText Typo="Typo.h1" Color="@Color.Error" Style="font-weight: bold;">Loadding...</MudText>
    </MudOverlay>
</div>

@code {
    private DateTime DateLog = DateTime.Today;
    private bool IsLoading;
    private readonly List<string> ShowLogs = new();
    private readonly List<LoggerModel> SearchLogs = new();
    private string? FilterLog { get; set; }
    private ElementReference LogContainerRef { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (!firstRender) return;

        await LoadLogs(true);
    }

    private async Task LoadLogs(bool firstRender)
    {
        try
        {
            if(!firstRender)
            {
                IsLoading = true;
                ShowLogs.Clear();
                StateHasChanged();
            }

            var Http = HttpClientFactory.CreateClient("RobotManagerAPI");
            var logs = await Http.GetFromJsonAsync<IEnumerable<string>>($"api/RobotManagerLogger/open-acs?date={DateLog}");
            ShowLogs.AddRange(logs ?? []);

            IsLoading = false;
            StateHasChanged();

            await ReloadLogs();
        }
        catch (AccessTokenNotAvailableException ex)
        {
            ex.Redirect();
            return;
        }
    }

    private async Task ReloadLogs()
    {
        IsLoading = true;
        SearchLogs.Clear();
        StateHasChanged();

        foreach (var line in ShowLogs.Where(log => string.IsNullOrEmpty(FilterLog) || log.Contains(FilterLog)).TakeLast(2000))
        {
            try
            {
                var log = System.Text.Json.JsonSerializer.Deserialize<LoggerModel>(line);
                if (log is not null) SearchLogs.Add(log);
            }
            catch (System.Text.Json.JsonException)
            {
                continue;
            }
        }

        IsLoading = false;
        StateHasChanged();
        await JSRuntime.InvokeVoidAsync("ScrollToBottom", LogContainerRef);
    }

    private async Task OnSearch(string text)
    {
        FilterLog = text;
        await ReloadLogs();
    }

    private async Task OnDateChanged(DateTime? date)
    {
        if (date is not null && date.HasValue)
        {
            DateLog = date.Value;
            await LoadLogs(false);
        }
    }
}
