@page "/emails"
@using AliasVault.RazorComponents.Tables
@inherits MainBase

<LayoutPageTitle>Emails</LayoutPageTitle>

<PageHeader
    BreadcrumbItems="@BreadcrumbItems"
    Title="Emails"
    Description="This page gives an overview of recently received mails by this AliasVault server. Note that all email fields except 'To' are encrypted with the public key of the user and cannot be decrypted by the server.">
    <CustomActions>
        <RefreshButton OnClick="RefreshData" ButtonText="Refresh" />
    </CustomActions>
</PageHeader>

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

        <SortableTable Columns="@_tableColumns" SortColumn="@SortColumn" SortDirection="@SortDirection" OnSortChanged="HandleSortChanged">
            @foreach (var email in EmailList)
            {
                <SortableTableRow>
                    <SortableTableColumn IsPrimary="true">@email.Id</SortableTableColumn>
                    <SortableTableColumn>@email.DateSystem.ToString("yyyy-MM-dd HH:mm")</SortableTableColumn>
                    <SortableTableColumn>@(email.FromLocal.Length > 15 ? email.FromLocal.Substring(0, 15) : email.FromLocal)@@@(email.FromDomain.Length > 15 ? email.FromDomain.Substring(0, 15) : email.FromDomain)</SortableTableColumn>
                    <SortableTableColumn>@email.ToLocal@@@email.ToDomain</SortableTableColumn>
                    <SortableTableColumn>@(email.Subject.Length > 30 ? email.Subject.Substring(0, 30) : email.Subject)</SortableTableColumn>
                    <SortableTableColumn>
                        <span class="line-clamp-1">
                            @(email.MessagePreview?.Length > 30 ? email.MessagePreview.Substring(0, 30) : email.MessagePreview)
                        </span>
                    </SortableTableColumn>
                    <SortableTableColumn>@email.Attachments.Count</SortableTableColumn>
                </SortableTableRow>
            }
        </SortableTable>
    </div>
}

@code {
    private readonly List<TableColumn> _tableColumns = [
        new TableColumn { Title = "ID", PropertyName = "Id" },
        new TableColumn { Title = "Time", PropertyName = "DateSystem" },
        new TableColumn { Title = "From", PropertyName = "From" },
        new TableColumn { Title = "To", PropertyName = "To" },
        new TableColumn { Title = "Subject", PropertyName = "Subject" },
        new TableColumn { Title = "Preview", PropertyName = "MessagePreview" },
        new TableColumn { Title = "Attachments", PropertyName = "Attachments" },
    ];

    private List<Email> EmailList { 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 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();

        IQueryable<Email> query = DbContext.Emails;

        // Apply sort
        switch (SortColumn)
        {
            case "Id":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Id)
                    : query.OrderByDescending(x => x.Id);
                break;
            case "DateSystem":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.DateSystem)
                    : query.OrderByDescending(x => x.DateSystem);
                break;
            case "From":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.FromLocal + "@" + x.FromDomain)
                    : query.OrderByDescending(x => x.FromLocal + "@" + x.FromDomain);
                break;
            case "To":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.ToLocal + "@" + x.ToDomain)
                    : query.OrderByDescending(x => x.ToLocal + "@" + x.ToDomain);
                break;
            case "Subject":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Subject)
                    : query.OrderByDescending(x => x.Subject);
                break;
            case "MessagePreview":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.MessagePreview)
                    : query.OrderByDescending(x => x.MessagePreview);
                break;
            case "Attachments":
                query = SortDirection == SortDirection.Ascending
                    ? query.OrderBy(x => x.Attachments.Count)
                    : query.OrderByDescending(x => x.Attachments.Count);
                break;
            default:
                query = query.OrderByDescending(x => x.DateSystem);
                break;
        }

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

        IsLoading = false;
        StateHasChanged();
    }
}
