@page "/logging/auth"
@using AliasVault.RazorComponents.Tables
@using AliasVault.Shared.Models.Enums
@inherits MainBase

<LayoutPageTitle>Auth logs</LayoutPageTitle>

<PageHeader
    BreadcrumbItems="@BreadcrumbItems"
    Title="Auth logs"
    Description="This page gives an overview of recent auth attempts.">
    <CustomActions>
        <DeleteButton OnClick="DeleteLogsWithConfirmation" ButtonText="Delete all logs" />
        <RefreshButton OnClick="RefreshData" ButtonText="Refresh" />
    </CustomActions>
</PageHeader>

@if (IsLoading)
{
    <LoadingIndicator />
}
else
{
    <div class="px-4">
        <Paginator CurrentPage="CurrentPage" PageSize="PageSize" TotalRecords="TotalRecords" OnPageChanged="HandlePageChanged" />

        <div class="mb-4 flex space-x-4">
            <div class="flex w-full">
                <div class="w-2/3 pr-2">
                    <input type="text" @bind-value="SearchTerm" @bind-value:event="oninput" id="search" placeholder="Search logs..." class="w-full px-4 py-2 border rounded text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
                </div>
                <div class="w-1/3 pl-2">
                    <select @bind="SelectedEventType" class="w-full px-4 py-2 border rounded text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white">
                        <option value="">All event types</option>
                        @foreach (var eventType in Enum.GetValues<AuthEventType>())
                        {
                            <option value="@eventType">@eventType</option>
                        }
                    </select>
                </div>
            </div>
        </div>

        <SortableTable Columns="@_tableColumns" SortColumn="@SortColumn" SortDirection="@SortDirection" OnSortChanged="HandleSortChanged">
            @foreach (var log in LogList)
            {
                <SortableTableRow>
                    <SortableTableColumn IsPrimary="true">@log.Id</SortableTableColumn>
                    <SortableTableColumn>@log.Timestamp.ToString("yyyy-MM-dd HH:mm")</SortableTableColumn>
                    <SortableTableColumn>@log.Username</SortableTableColumn>
                    <SortableTableColumn>@log.EventType</SortableTableColumn>
                    <SortableTableColumn><StatusPill Enabled="log.IsSuccess" TextTrue="Success" TextFalse="Failed" /></SortableTableColumn>
                    <SortableTableColumn>@log.IpAddress</SortableTableColumn>
                </SortableTableRow>
            }
        </SortableTable>
    </div>
}

@code {
    private readonly List<TableColumn> _tableColumns = [
        new TableColumn { Title = "ID", PropertyName = "Id" },
        new TableColumn { Title = "Time", PropertyName = "Timestamp" },
        new TableColumn { Title = "Username", PropertyName = "Username" },
        new TableColumn { Title = "Event", PropertyName = "EventType" },
        new TableColumn { Title = "Success", PropertyName = "IsSuccess" },
        new TableColumn { Title = "IP", PropertyName = "IpAddress" },
    ];

    private List<AuthLog> LogList { get; set; } = [];
    private bool IsLoading { get; set; } = true;
    private int CurrentPage { get; set; } = 1;
    private int PageSize { get; set; } = 50;
    private int TotalRecords { get; set; }

    private string _searchTerm = string.Empty;
    private string SearchTerm
    {
        get => _searchTerm;
        set
        {
            if (_searchTerm != value)
            {
                _searchTerm = value;
                _ = RefreshData();
            }
        }
    }

    private string _selectedEventType = string.Empty;
    private string SelectedEventType
    {
        get => _selectedEventType;
        set
        {
            if (_selectedEventType != value)
            {
                _selectedEventType = value;
                _ = RefreshData();
            }
        }
    }

    private string SortColumn { get; set; } = "Id";
    private SortDirection SortDirection { get; set; } = SortDirection.Descending;

    private async Task HandleSortChanged((string column, SortDirection direction) sort)
    {
        SortColumn = sort.column;
        SortDirection = sort.direction;
        await RefreshData();
    }

    /// <inheritdoc />
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await RefreshData();
        }
    }

    private void HandlePageChanged(int newPage)
    {
        CurrentPage = newPage;
        _ = RefreshData();
    }

    private async Task RefreshData()
    {
        IsLoading = true;
        StateHasChanged();

        var query = DbContext.AuthLogs.AsQueryable();

        if (!string.IsNullOrEmpty(SearchTerm))
        {
            query = query.Where(x => EF.Functions.Like(x.Username.ToLower(), "%" + SearchTerm.ToLower() + "%"));
        }

        if (!string.IsNullOrEmpty(SelectedEventType))
        {
            var success = Enum.TryParse<AuthEventType>(SelectedEventType, out var eventType);
            if (success)
            {
                query = query.Where(x => x.EventType == eventType);
            }
        }

        query = ApplySort(query);

        TotalRecords = await query.CountAsync();
        LogList = await query
            .Skip((CurrentPage - 1) * PageSize)
            .Take(PageSize)
            .ToListAsync();

        IsLoading = false;
        StateHasChanged();
    }

    /// <summary>
    /// Apply sort to the query.
    /// </summary>
    private IQueryable<AuthLog> ApplySort(IQueryable<AuthLog> query)
    {
        // Apply sort.
        switch (SortColumn)
        {
            case "Timestamp":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Timestamp)
                    : query.OrderByDescending(x => x.Timestamp);
                break;
            case "Username":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Username)
                    : query.OrderByDescending(x => x.Username);
                break;
            case "EventType":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.EventType)
                    : query.OrderByDescending(x => x.EventType);
                break;
            case "IsSuccess":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.IsSuccess)
                    : query.OrderByDescending(x => x.IsSuccess);
                break;
            case "IpAddress":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.IpAddress)
                    : query.OrderByDescending(x => x.IpAddress);
                break;
            default:
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Id)
                    : query.OrderByDescending(x => x.Id);
                break;
        }

        return query;
    }

    private async Task DeleteLogsWithConfirmation()
    {
        if (await ConfirmModalService.ShowConfirmation("Confirm Delete", "Are you sure you want to delete all logs? This action cannot be undone."))
        {
            await DeleteLogs();
        }
    }

    private async Task DeleteLogs()
    {
        IsLoading = true;
        StateHasChanged();

        DbContext.AuthLogs.RemoveRange(DbContext.AuthLogs);
        await DbContext.SaveChangesAsync();
        await RefreshData();

        IsLoading = false;
        StateHasChanged();
    }
}
