@page "/admin/servers/manager"
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Moonlight.App.Services
@using Moonlight.App.Services.Interop
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Daemon.Resources
@using Moonlight.App.Models.Wings
@using BlazorTable
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Helpers

@inject NodeRepository NodeRepository
@inject NodeService NodeService
@inject ServerRepository ServerRepository
@inject SmartTranslateService SmartTranslateService
@inject AlertService AlertService
@inject ServerService ServerService

<OnlyAdmin>
    <div class="card mb-5">
        <div class="card-body">
            <WButton Text="@(SmartTranslateService.Translate("Refresh"))"
                     WorkingText="@(SmartTranslateService.Translate("Working"))"
                     CssClasses="btn-primary"
                     OnClick="() => LazyLoader.Reload()">
            </WButton>
            <WButton Text="@(SmartTranslateService.Translate("Stop all"))"
                     WorkingText="@(SmartTranslateService.Translate("Working"))"
                     CssClasses="btn-danger"
                     OnClick="StopAll">
            </WButton>
            <WButton Text="@(SmartTranslateService.Translate("Kill all"))"
                     WorkingText="@(SmartTranslateService.Translate("Working"))"
                     CssClasses="btn-danger"
                     OnClick="KillAll">
            </WButton>
        </div>
    </div>
    <LazyLoader @ref="LazyLoader" Load="Load">
        <div class="card card-body">
            <div class="table-responsive">
                <Table TableItem="ContainerStats.Container" Items="Containers.Values" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
                        <Template>
                            @{
                                var server = Containers.First(x => x.Value == context).Key;
                            }

                            <a href="/server/@(server.Uuid)">@(server.Name)</a>
                        </Template>
                    </Column>
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Cpu usage"))" Field="@(x => x.Cpu)" Sortable="true" Filterable="true">
                        <Template>
                            <span>@(context.Cpu)%</span>
                        </Template>
                    </Column>
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Memory usage"))" Field="@(x => x.Memory)" Sortable="true" Filterable="true">
                        <Template>
                            <span>@(Formatter.FormatSize(context.Memory))</span>
                        </Template>
                    </Column>
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Network in"))" Field="@(x => x.NetworkIn)" Sortable="true" Filterable="true">
                        <Template>
                            <span>@(Formatter.FormatSize(context.NetworkIn))</span>
                        </Template>
                    </Column>
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Network out"))" Field="@(x => x.NetworkOut)" Sortable="true" Filterable="true">
                        <Template>
                            <span>@(Formatter.FormatSize(context.NetworkOut))</span>
                        </Template>
                    </Column>
                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Owner"))" Field="@(x => x.Name)" Sortable="false" Filterable="false">
                        <Template>
                            @{
                                var server = Containers.First(x => x.Value == context).Key;
                            }

                            <a href="/admin/users/view/@(server.Owner.Id)/">@server.Owner.Email</a>
                        </Template>
                    </Column>
                    <Pager ShowPageNumber="true" ShowTotalCount="true"/>
                </Table>
            </div>
        </div>
    </LazyLoader>
</OnlyAdmin>

@code
{
    private LazyLoader LazyLoader;

    private Dictionary<Server, ContainerStats.Container> Containers = new();

    private async Task Load(LazyLoader lazyLoader)
    {
        Containers.Clear();

        foreach (var node in NodeRepository.Get().ToArray())
        {
            await lazyLoader.SetText(node.Name);

            try
            {
                var containerStats = await NodeService.GetContainerStats(node);

                foreach (var container in containerStats.Containers)
                {
                    if (Guid.TryParse(container.Name, out Guid uuid))
                    {
                        var server = ServerRepository
                            .Get()
                            .Include(x => x.Owner)
                            .FirstOrDefault(x => x.Uuid == uuid);

                        if (server != null)
                        {
                            Containers.Add(server, container);
                        }
                    }
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
    }

    private async Task StopAll()
    {
        var b = await AlertService.YesNo(
            SmartTranslateService.Translate("Stop all servers"),
            SmartTranslateService.Translate("Do you really want to stop all running servers?"),
            SmartTranslateService.Translate("Yes"),
            SmartTranslateService.Translate("No")
            );

        if (b)
        {
            foreach (var containerData in Containers)
            {
                await ServerService.SetPowerState(containerData.Key, PowerSignal.Stop);
            }
        }
    }

    private async Task KillAll()
    {
        var b = await AlertService.YesNo(
            SmartTranslateService.Translate("Kill all servers"),
            SmartTranslateService.Translate("Do you really want to kill all running servers?"),
            SmartTranslateService.Translate("Yes"),
            SmartTranslateService.Translate("No")
            );

        if (b)
        {
            foreach (var containerData in Containers)
            {
                await ServerService.SetPowerState(containerData.Key, PowerSignal.Kill);
            }
        }
    }
}