@page "/all-time-stats"
@using AliasVault.Admin.Main.Models
@using AliasVault.Admin.Services
@using AliasVault.Admin.Main.Pages.Dashboard.Components
@using AliasVault.RazorComponents.Tables
@using AliasVault.RazorComponents
@inherits MainBase
@inject StatisticsService StatisticsService

<LayoutPageTitle>All-Time Statistics</LayoutPageTitle>

<PageHeader
    BreadcrumbItems="@BreadcrumbItems"
    Title="All-Time Statistics"
    Description="View metrics and insights into the usage totals of this AliasVault server.">
    <CustomActions>
        <RefreshButton OnClick="RefreshData" ButtonText="Refresh" />
    </CustomActions>
</PageHeader>

<div class="px-4 space-y-6">
    <!-- Overview Statistics Cards -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center">
                <div class="ml-4">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Users</h3>
                    @if (_totalUsers.HasValue)
                    {
                        <p class="text-2xl font-bold text-gray-900 dark:text-white">@_totalUsers.Value.ToString("N0")</p>
                    }
                    else
                    {
                        <div class="w-16 h-6 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
                    }
                </div>
            </div>
        </div>

        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center">
                <div class="ml-4">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Email Aliases</h3>
                    @if (_totalAliases.HasValue)
                    {
                        <p class="text-2xl font-bold text-gray-900 dark:text-white">@_totalAliases.Value.ToString("N0")</p>
                    }
                    else
                    {
                        <div class="w-16 h-6 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
                    }
                </div>
            </div>
        </div>

        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center">
                <div class="ml-4">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Emails</h3>
                    @if (_totalEmails.HasValue)
                    {
                        <p class="text-2xl font-bold text-gray-900 dark:text-white">@_totalEmails.Value.ToString("N0")</p>
                    }
                    else
                    {
                        <div class="w-16 h-6 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
                    }
                </div>
            </div>
        </div>

        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center">
                <div class="ml-4">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Email attachments</h3>
                    @if (_totalEmailAttachments.HasValue)
                    {
                        <p class="text-2xl font-bold text-gray-900 dark:text-white">@_totalEmailAttachments.Value.ToString("N0")</p>
                    }
                    else
                    {
                        <div class="w-16 h-6 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
                    }
                </div>
            </div>
        </div>
    </div>

    <!-- Top Users Analysis -->
    <div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
        <!-- Top Users by Storage -->
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top Users by Storage</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">Users with the largest vault storage requirements</p>
                </div>
            </div>
            @if (_topUsersByStorage != null)
            {
                <div class="overflow-x-auto">
                    <SortableTable Columns="@_storageTableColumns">
                        @{
                            var storageStartIndex = (_storageCurrentPage - 1) * _pageSize + 1;
                            var storageIndex = storageStartIndex;
                        }
                        @foreach (var user in _topUsersByStorage)
                        {
                            <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
                                <td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-center w-12">@storageIndex</td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100">
                                    <UserNameDisplay User="@user.User" />
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right w-32">@user.StorageDisplaySize</td>
                            </tr>
                            storageIndex++;
                        }
                    </SortableTable>
                </div>
                <ResponsivePaginator CurrentPage="_storageCurrentPage" PageSize="_pageSize" TotalRecords="_storageTotalRecords" OnPageChanged="HandleStoragePageChanged" />
            }
            else
            {
                <div class="px-6 py-8 flex justify-center">
                    <LoadingIndicator />
                </div>
            }
        </div>


        <!-- Top Users by Credentials -->
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top Users by Credentials</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">Users with the most credentials stored in their vault</p>
                </div>
            </div>
            @if (_topUsersByCredentials != null)
            {
                <div class="overflow-x-auto">
                    <SortableTable Columns="@_credentialTableColumns">
                        @{
                            var credentialStartIndex = (_credentialCurrentPage - 1) * _pageSize + 1;
                            var credentialIndex = credentialStartIndex;
                        }
                        @foreach (var user in _topUsersByCredentials)
                        {
                            <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
                                <td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-center w-12">@credentialIndex</td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100">
                                    <UserNameDisplay User="@user.User" />
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right w-24">@user.CredentialCount.ToString("N0")</td>
                            </tr>
                            credentialIndex++;
                        }
                    </SortableTable>
                </div>
                <ResponsivePaginator CurrentPage="_credentialCurrentPage" PageSize="_pageSize" TotalRecords="_credentialTotalRecords" OnPageChanged="HandleCredentialPageChanged" />
            }
            else
            {
                <div class="px-6 py-8 flex justify-center">
                    <LoadingIndicator />
                </div>
            }
        </div>

        <!-- Top Users by Aliases -->
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top Users by Aliases</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">Users with the most email aliases created</p>
                </div>
            </div>
            @if (_topUsersByAliases != null)
            {
                <div class="overflow-x-auto">
                    <SortableTable Columns="@_aliasTableColumns">
                        @{
                            var aliasStartIndex = (_aliasCurrentPage - 1) * _pageSize + 1;
                            var aliasIndex = aliasStartIndex;
                        }
                        @foreach (var user in _topUsersByAliases)
                        {
                            <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
                                <td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-center w-12">@aliasIndex</td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100">
                                    <UserNameDisplay User="@user.User" />
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right w-24">@user.AliasCount.ToString("N0")</td>
                            </tr>
                            aliasIndex++;
                        }
                    </SortableTable>
                </div>
                <ResponsivePaginator CurrentPage="_aliasCurrentPage" PageSize="_pageSize" TotalRecords="_aliasTotalRecords" OnPageChanged="HandleAliasPageChanged" />
            }
            else
            {
                <div class="px-6 py-8 flex justify-center">
                    <LoadingIndicator />
                </div>
            }
        </div>

        <!-- Top Users by Emails -->
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top Users by Emails</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">Users with the most emails stored</p>
                </div>
            </div>
            @if (_topUsersByEmails != null)
            {
                <div class="overflow-x-auto">
                    <SortableTable Columns="@_emailTableColumns">
                        @{
                            var emailStartIndex = (_emailCurrentPage - 1) * _pageSize + 1;
                            var emailIndex = emailStartIndex;
                        }
                        @foreach (var user in _topUsersByEmails)
                        {
                            <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
                                <td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-center w-12">@emailIndex</td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100">
                                    <UserNameDisplay User="@user.User" />
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right w-24">@user.EmailCount.ToString("N0")</td>
                            </tr>
                            emailIndex++;
                        }
                    </SortableTable>
                </div>
                <ResponsivePaginator CurrentPage="_emailCurrentPage" PageSize="_pageSize" TotalRecords="_emailTotalRecords" OnPageChanged="HandleEmailPageChanged" />
            }
            else
            {
                <div class="px-6 py-8 flex justify-center">
                    <LoadingIndicator />
                </div>
            }
        </div>
    </div>

    <!-- Top IP Addresses -->
    <div class="mt-6">
    @if (_topIpAddresses != null && _topIpAddresses.Any())
    {
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top IP Address Ranges</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">IP ranges with the most associated user accounts (last octet anonymized, successful logins only)</p>
                </div>
            </div>
            <div class="overflow-x-auto">
                <SortableTable Columns="@_ipTableColumns">
                    @foreach (var ip in _topIpAddresses)
                    {
                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-100 font-mono">
                                <a href="logging/auth?search=@Uri.EscapeDataString(ip.OriginalIpAddress)" class="text-gray-900 dark:text-gray-100 hover:text-blue-600 dark:hover:text-blue-400 cursor-pointer">
                                    @ip.IpAddress
                                </a>
                            </td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right">@ip.UniqueUserCount.ToString("N0")</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right">@ip.LastActivity.ToString("MMM dd, yyyy HH:mm")</td>
                        </tr>
                    }
                </SortableTable>
            </div>
        </div>
    }
    else if (_topIpAddresses != null && !_topIpAddresses.Any())
    {
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="text-center text-gray-500 dark:text-gray-400">
                <svg class="mx-auto h-12 w-12 text-gray-300 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
                </svg>
                <h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-white">No IP Address Data</h3>
                <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">IP addresses are fully anonymized or no successful logins recorded.</p>
            </div>
        </div>
    }
    else if (_ipAddressesLoading)
    {
        <div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 sm:p-6 dark:bg-gray-800">
            <div class="flex items-center justify-between mb-4">
                <div>
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Top IP Address Ranges</h3>
                    <p class="text-sm text-gray-500 dark:text-gray-400">IP ranges with the most associated user accounts (last octet anonymized, successful logins only)</p>
                </div>
            </div>
            <div class="px-6 py-8 flex justify-center">
                <LoadingIndicator />
            </div>
        </div>
    }
    </div>

    @if (_loadingError)
    {
        <div class="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4">
            <div class="flex">
                <div class="flex-shrink-0">
                    <svg class="h-5 w-5 text-red-400" fill="currentColor" viewBox="0 0 20 20">
                        <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
                    </svg>
                </div>
                <div class="ml-3">
                    <h3 class="text-sm font-medium text-red-800 dark:text-red-200">Error Loading Statistics</h3>
                    <p class="text-sm text-red-700 dark:text-red-300 mt-1">Unable to retrieve some server statistics. Please try refreshing the page.</p>
                </div>
            </div>
        </div>
    }
</div>

@code {
    // Basic statistics (loaded first for immediate feedback)
    private int? _totalUsers;
    private int? _totalAliases;
    private int? _totalEmails;
    private int? _totalEmailAttachments;

    // Detailed statistics (loaded separately)
    private List<TopUserByStorage>? _topUsersByStorage;
    private List<TopUserByAliases>? _topUsersByAliases;
    private List<TopUserByEmails>? _topUsersByEmails;
    private List<TopUserByCredentials>? _topUsersByCredentials;
    private List<TopIpAddress>? _topIpAddresses;
    private bool _ipAddressesLoading = true;
    private bool _loadingError = false;

    // Pagination variables
    private const int _pageSize = 10;
    private int _storageCurrentPage = 1;
    private int _aliasCurrentPage = 1;
    private int _emailCurrentPage = 1;
    private int _credentialCurrentPage = 1;
    private int _storageTotalRecords = 0;
    private int _aliasTotalRecords = 0;
    private int _emailTotalRecords = 0;
    private int _credentialTotalRecords = 0;

    private readonly List<TableColumn> _storageTableColumns = new()
    {
        new() { Title = "#", PropertyName = "Index", Sortable = false },
        new() { Title = "User", PropertyName = "Username", Sortable = false },
        new() { Title = "Storage", PropertyName = "StorageDisplaySize", Sortable = false }
    };

    private readonly List<TableColumn> _aliasTableColumns = new()
    {
        new() { Title = "#", PropertyName = "Index", Sortable = false },
        new() { Title = "User", PropertyName = "Username", Sortable = false },
        new() { Title = "Aliases", PropertyName = "AliasCount", Sortable = false }
    };

    private readonly List<TableColumn> _emailTableColumns = new()
    {
        new() { Title = "#", PropertyName = "Index", Sortable = false },
        new() { Title = "User", PropertyName = "Username", Sortable = false },
        new() { Title = "Emails", PropertyName = "EmailCount", Sortable = false }
    };

    private readonly List<TableColumn> _credentialTableColumns = new()
    {
        new() { Title = "#", PropertyName = "Index", Sortable = false },
        new() { Title = "User", PropertyName = "Username", Sortable = false },
        new() { Title = "Credentials", PropertyName = "CredentialCount", Sortable = false }
    };

    private readonly List<TableColumn> _ipTableColumns = new()
    {
        new() { Title = "IP Range", PropertyName = "IpAddress", Sortable = false },
        new() { Title = "Users", PropertyName = "UniqueUserCount", Sortable = false },
        new() { Title = "Last Activity", PropertyName = "LastActivity", Sortable = false }
    };

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        BreadcrumbItems.Add(new BreadcrumbItem { DisplayName = "All-Time Statistics" });

        // Load statistics asynchronously for better perceived performance
        _ = LoadBasicStatisticsAsync();
        _ = LoadDetailedStatisticsAsync();
    }

    private void RefreshData()
    {
        // Reset all data
        _totalUsers = null;
        _totalAliases = null;
        _totalEmails = null;
        _totalEmailAttachments = null;
        _topUsersByStorage = null;
        _topUsersByAliases = null;
        _topUsersByEmails = null;
        _topUsersByCredentials = null;
        _topIpAddresses = null;
        _ipAddressesLoading = true;
        _loadingError = false;

        // Reset pagination
        _storageCurrentPage = 1;
        _aliasCurrentPage = 1;
        _emailCurrentPage = 1;
        _credentialCurrentPage = 1;
        _storageTotalRecords = 0;
        _aliasTotalRecords = 0;
        _emailTotalRecords = 0;
        _credentialTotalRecords = 0;

        StateHasChanged();

        // Reload statistics
        _ = LoadBasicStatisticsAsync();
        _ = LoadDetailedStatisticsAsync();
    }

    private async Task LoadBasicStatisticsAsync()
    {
        try
        {
            var stats = await StatisticsService.GetServerStatisticsAsync();

            _totalUsers = stats.TotalUsers;
            _totalAliases = stats.TotalAliases;
            _totalEmails = stats.TotalEmails;
            _totalEmailAttachments = stats.TotalEmailAttachments;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading basic statistics: {ex.Message}");
            _loadingError = true;
            StateHasChanged();
        }
    }

    private async Task LoadDetailedStatisticsAsync()
    {
        try
        {
            // Load paginated data for all four tables
            var storageTask = StatisticsService.GetTopUsersByStoragePaginatedAsync(_storageCurrentPage, _pageSize);
            var aliasTask = StatisticsService.GetTopUsersByAliasesPaginatedAsync(_aliasCurrentPage, _pageSize);
            var emailTask = StatisticsService.GetTopUsersByEmailsPaginatedAsync(_emailCurrentPage, _pageSize);
            var credentialTask = StatisticsService.GetTopUsersByCredentialsPaginatedAsync(_credentialCurrentPage, _pageSize);
            var ipTask = StatisticsService.GetServerStatisticsAsync();

            await Task.WhenAll(storageTask, aliasTask, emailTask, credentialTask, ipTask);

            var (storageUsers, storageTotalCount) = await storageTask;
            var (aliasUsers, aliasTotalCount) = await aliasTask;
            var (emailUsers, emailTotalCount) = await emailTask;
            var (credentialUsers, credentialTotalCount) = await credentialTask;
            var stats = await ipTask;

            _topUsersByStorage = storageUsers;
            _storageTotalRecords = storageTotalCount;

            _topUsersByAliases = aliasUsers;
            _aliasTotalRecords = aliasTotalCount;

            _topUsersByEmails = emailUsers;
            _emailTotalRecords = emailTotalCount;

            _topUsersByCredentials = credentialUsers;
            _credentialTotalRecords = credentialTotalCount;

            _topIpAddresses = stats.TopIpAddresses;
            _ipAddressesLoading = false;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading detailed statistics: {ex.Message}");
            _loadingError = true;
            _ipAddressesLoading = false;
            StateHasChanged();
        }
    }

    private async Task HandleStoragePageChanged(int newPage)
    {
        _storageCurrentPage = newPage;
        await LoadStoragePageData();
    }

    private async Task HandleAliasPageChanged(int newPage)
    {
        _aliasCurrentPage = newPage;
        await LoadAliasPageData();
    }

    private async Task HandleEmailPageChanged(int newPage)
    {
        _emailCurrentPage = newPage;
        await LoadEmailPageData();
    }

    private async Task HandleCredentialPageChanged(int newPage)
    {
        _credentialCurrentPage = newPage;
        await LoadCredentialPageData();
    }

    private async Task LoadStoragePageData()
    {
        try
        {
            _topUsersByStorage = null;
            StateHasChanged();

            var (users, totalCount) = await StatisticsService.GetTopUsersByStoragePaginatedAsync(_storageCurrentPage, _pageSize);
            _topUsersByStorage = users;
            _storageTotalRecords = totalCount;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading storage statistics: {ex.Message}");
        }
    }

    private async Task LoadAliasPageData()
    {
        try
        {
            _topUsersByAliases = null;
            StateHasChanged();

            var (users, totalCount) = await StatisticsService.GetTopUsersByAliasesPaginatedAsync(_aliasCurrentPage, _pageSize);
            _topUsersByAliases = users;
            _aliasTotalRecords = totalCount;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading alias statistics: {ex.Message}");
        }
    }

    private async Task LoadEmailPageData()
    {
        try
        {
            _topUsersByEmails = null;
            StateHasChanged();

            var (users, totalCount) = await StatisticsService.GetTopUsersByEmailsPaginatedAsync(_emailCurrentPage, _pageSize);
            _topUsersByEmails = users;
            _emailTotalRecords = totalCount;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading email statistics: {ex.Message}");
        }
    }

    private async Task LoadCredentialPageData()
    {
        try
        {
            _topUsersByCredentials = null;
            StateHasChanged();

            var (users, totalCount) = await StatisticsService.GetTopUsersByCredentialsPaginatedAsync(_credentialCurrentPage, _pageSize);
            _topUsersByCredentials = users;
            _credentialTotalRecords = totalCount;

            StateHasChanged();
        }
        catch (Exception ex)
        {
            GlobalNotificationService.AddErrorMessage($"Error loading credential statistics: {ex.Message}");
        }
    }
}