@page "/admin/users/sessions"

@using Moonlight.Shared.Components.Navigations
@using Moonlight.App.Services.Sessions
@using BlazorTable
@using Moonlight.App.Helpers
@using Moonlight.App.Models.Misc
@using Moonlight.App.Services
@using Moonlight.App.Services.Interop

@inject SessionServerService SessionServerService
@inject SmartTranslateService SmartTranslateService
@inject AlertService AlertService
@inject ToastService ToastService

@attribute [PermissionRequired(nameof(Permissions.AdminUserSessions))]

<AdminSessionNavigation Index="1"/>

<div class="card">
    <LazyLoader Load="Load">
        <div class="card-header border-0 pt-5">
            <h3 class="card-title align-items-start flex-column">
                <span class="card-label fw-bold fs-3 mb-1">
                    <TL>Sessions</TL>
                </span>
            </h3>
            <div class="card-toolbar">
                <button class="btn btn-sm btn-primary me-3" @onclick="Refresh">
                    <i class="bx bx-revision"></i>
                    <TL>Refresh</TL>
                </button>
                <button class="btn btn-sm btn-warning" @onclick="MessageAll">
                    <i class="bx bx-message-square-dots"></i>
                    <TL>Send a message to all users</TL>
                </button>
            </div>
        </div>
        <div class="card-body pt-0">
            @if (AllSessions == null)
            {
                <div class="alert alert-info">
                    <span class="spinner-border spinner-border-sm align-middle me-2"></span>
                    <TL>Loading sessions</TL>
                </div>
            }
            else
            {
                <Table TableItem="SessionClientService" Items="AllSessions" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("Email"))" Field="@(x => x.User.Email)" Sortable="true" Filterable="true" Width="20%">
                        <Template>
                            @if (context.User == null)
                            {
                                <TL>Guest</TL>
                            }
                            else
                            {
                                <a href="/admin/users/view/@(context.User.Id)">@(context.User.Email)</a>
                            }
                        </Template>
                    </Column>
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("IP"))" Field="@(x => x.Uuid)" Sortable="false" Filterable="false" Width="10%">
                        <Template>
                            @(context.Ip)
                        </Template>
                    </Column>
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("URL"))" Field="@(x => x.NavigationManager.Uri)" Sortable="true" Filterable="true" Width="10%"/>
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("Device"))" Field="@(x => x.Uuid)" Sortable="false" Filterable="false" Width="10%">
                        <Template>
                            @(context.Device)
                        </Template>
                    </Column>
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("Time"))" Field="@(x => x.CreateTimestamp)" Sortable="true" Filterable="true" Width="10%">
                        <Template>
                            @{
                                var time = Formatter.FormatUptime((DateTime.UtcNow - context.CreateTimestamp).TotalMilliseconds);
                            }
                            <span>@(time)</span>
                        </Template>
                    </Column>
                    <Column TableItem="SessionClientService" Title="@(SmartTranslateService.Translate("Actions"))" Field="@(x => x.Uuid)" Sortable="false" Filterable="false" Width="10%">
                        <Template>
                            <button @onclick="() => Navigate(context)" class="btn btn-sm btn-primary">
                                <TL>Change url</TL>
                            </button>
                        </Template>
                    </Column>
                    <Column TableItem="SessionClientService" Title="" Field="@(x => x.Uuid)" Sortable="false" Filterable="false" Width="10%">
                        <Template>
                            <button @onclick="() => Message(context)" class="btn btn-sm btn-warning">
                                <TL>Message</TL>
                            </button>
                        </Template>
                    </Column>
                    <Pager ShowPageNumber="true" ShowTotalCount="true"/>
                </Table>
            }
        </div>
    </LazyLoader>
</div>

@code
{
    private SessionClientService[]? AllSessions;

    private async Task Load(LazyLoader arg)
    {
        AllSessions = await SessionServerService.GetSessions();

        Task.Run(async () =>
        {
            while (true)
            {
                try
                {
                    await Refresh();
                    await Task.Delay(1000);
                }
                catch (Exception e)
                {
                    Logger.Warn("Error auto refreshing sessions");
                    Logger.Warn(e);
                }
            }
        });
    }

    private async Task Refresh()
    {
        AllSessions = await SessionServerService.GetSessions();
        await InvokeAsync(StateHasChanged);
    }

    private async Task Navigate(SessionClientService session)
    {
        var url = await AlertService.Text("URL", SmartTranslateService.Translate("Enter url"), "");

        if (string.IsNullOrEmpty(url))
            return;

        if (url == "null")
            return;

        session.NavigationManager.NavigateTo(url, true);
    }

    private async Task MessageAll()
    {
        var message = await AlertService.Text(
            SmartTranslateService.Translate("Enter message"),
            SmartTranslateService.Translate("Enter the message to send"),
            ""
            );

        var b = await AlertService.YesNo(
            SmartTranslateService.Translate("Confirm"),
            SmartTranslateService.Translate("Are you sure?"),
            SmartTranslateService.Translate("Yes"),
            SmartTranslateService.Translate("No")
            );

        if (b)
        {
            foreach (var session in AllSessions!)
            {
                Task.Run(async () =>
                {
                    try
                    {
                        await session.AlertService.Warning("Admin Message", message);
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Error sending user a alert");
                        Logger.Warn(e);

                        var translation = SmartTranslateService.Translate("An unknown error occured while sending admin message to user: ");
                        var identifier = session.User != null ? session.User.Email : session.Uuid.ToString();

                        await ToastService.Warning(translation + identifier);
                    }
                });
            }
        }
    }

    private async Task Message(SessionClientService session)
    {
        var message = await AlertService.Text(
            SmartTranslateService.Translate("Enter message"),
            SmartTranslateService.Translate("Enter the message to send"),
            ""
            );

        var b = await AlertService.YesNo(
            SmartTranslateService.Translate("Confirm"),
            SmartTranslateService.Translate("Are you sure?"),
            SmartTranslateService.Translate("Yes"),
            SmartTranslateService.Translate("No")
            );

        if (b)
        {
            try
            {
                await session.AlertService.Warning("Admin Message", message!);
            }
            catch (Exception e)
            {
                Logger.Warn("Error sending user a alert");
                Logger.Warn(e);

                await ToastService.Warning(SmartTranslateService.Translate("An unknown error occured while sending admin message"));
            }
        }
    }
}