@page "/servers"
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@using Moonlight.App.Services

@inject ServerRepository ServerRepository
@inject IServiceScopeFactory ServiceScopeFactory

<LazyLoader Load="Load">
@if (AllServers.Any())
{
    if (UseSortedServerView)
    {
        var groupedServers = AllServers
            .OrderBy(x => x.Name)
            .GroupBy(x => x.Image.Name);

        foreach (var groupedServer in groupedServers)
        {
            <div class="separator separator-content my-15">@(groupedServer.Key)</div>
            <div class="card card-body bg-secondary py-0 my-0 mx-0 px-0">
                @foreach (var server in groupedServer)
                {
                    <div class="row mx-4 my-4">
                            <a class="card card-body" href="/server/@(server.Uuid)">
                                <div class="row">
                                    <div class="col">
                                        <div class="d-flex align-items-center">
                                            <div class="symbol symbol-50px me-3">
                                                <i class="bx bx-md bx-server"></i>
                                            </div>
                                            <div class="d-flex justify-content-start flex-column">
                                                <a href="/server/@(server.Uuid)" class="text-gray-800 text-hover-primary mb-1 fs-5">
                                                    @(server.Name)
                                                </a>
                                                <span class="text-gray-400 fw-semibold d-block fs-6">
                                                    @(Math.Round(server.Memory / 1024D, 2)) GB / @(Math.Round(server.Disk / 1024D, 2)) GB / @(server.Node.Name) <span class="text-gray-700">- @(server.Image.Name)</span>
                                                </span>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="d-none d-sm-block col my-auto fs-6">
                                        @(server.Node.Fqdn):@(server.MainAllocation.Port)
                                    </div>
                                    <div class="d-none d-sm-block col my-auto fs-6">
                                        @if (StatusCache.ContainsKey(server))
                                        {
                                            var status = StatusCache[server];

                                            switch (status)
                                            {
                                                case "offline":
                                                    <span class="text-danger">
                                                        <TL>Offline</TL>
                                                    </span>
                                                    break;
                                                case "stopping":
                                                    <span class="text-warning">
                                                        <TL>Stopping</TL>
                                                    </span>
                                                    break;
                                                case "starting":
                                                    <span class="text-warning">
                                                        <TL>Starting</TL>
                                                    </span>
                                                    break;
                                                case "running":
                                                    <span class="text-success">
                                                        <TL>Running</TL>
                                                    </span>
                                                    break;
                                                case "failed":
                                                    <span class="text-gray-400">
                                                        <TL>Failed</TL>
                                                    </span>
                                                    break;
                                                default:
                                                    <span class="text-danger">
                                                        <TL>Offline</TL>
                                                    </span>
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            <span class="text-gray-400">
                                                <TL>Loading</TL>
                                            </span>
                                        }
                                    </div>
                                </div>
                            </a>
                        </div>
                }
            </div>
        }
    }
    else
    {
        foreach (var server in AllServers)
        {
            <div class="row px-5 mb-5">
                <a class="card card-body" href="/server/@(server.Uuid)">
                    <div class="row">
                        <div class="col">
                            <div class="d-flex align-items-center">
                                <div class="symbol symbol-50px me-3">
                                    <i class="bx bx-md bx-server"></i>
                                </div>
                                <div class="d-flex justify-content-start flex-column">
                                    <a href="/server/@(server.Uuid)" class="text-gray-800 text-hover-primary mb-1 fs-5">
                                        @(server.Name)
                                    </a>
                                    <span class="text-gray-400 fw-semibold d-block fs-6">
                                        @(Math.Round(server.Memory / 1024D, 2)) GB / @(Math.Round(server.Disk / 1024D, 2)) GB / @(server.Node.Name) <span class="text-gray-700">- @(server.Image.Name)</span>
                                    </span>
                                </div>
                            </div>
                        </div>
                        <div class="d-none d-sm-block col my-auto fs-6">
                            @(server.Node.Fqdn):@(server.MainAllocation.Port)
                        </div>
                        <div class="d-none d-sm-block col my-auto fs-6">
                            @if (StatusCache.ContainsKey(server))
                            {
                                var status = StatusCache[server];

                                switch (status)
                                {
                                    case "offline":
                                        <span class="text-danger">
                                            <TL>Offline</TL>
                                        </span>
                                        break;
                                    case "stopping":
                                        <span class="text-warning">
                                            <TL>Stopping</TL>
                                        </span>
                                        break;
                                    case "starting":
                                        <span class="text-warning">
                                            <TL>Starting</TL>
                                        </span>
                                        break;
                                    case "running":
                                        <span class="text-success">
                                            <TL>Running</TL>
                                        </span>
                                        break;
                                    case "failed":
                                        <span class="text-gray-400">
                                            <TL>Failed</TL>
                                        </span>
                                        break;
                                    default:
                                        <span class="text-danger">
                                            <TL>Offline</TL>
                                        </span>
                                        break;
                                }
                            }
                            else
                            {
                                <span class="text-gray-400">
                                    <TL>Loading</TL>
                                </span>
                            }
                        </div>
                    </div>
                </a>
            </div>
        }
    }
}
else
{
    <div class="alert bg-info d-flex flex-column flex-sm-row w-100 p-5">
        <div class="d-flex flex-column pe-0 pe-sm-10">
            <h4 class="fw-semibold">
                <TL>You have no servers</TL>
            </h4>
            <span>
                <TL>We were not able to find any servers associated with your account</TL>
            </span>
        </div>
    </div>
}

<div class="row mt-7 px-3">
    <div class="card">
        <div class="card-header">
            <div class="card-title">
                <span class="badge badge-primary badge-lg">Beta</span>
            </div>
        </div>
        <div class="card-body">
            <div class="row">
                <label class="col-lg-4 col-form-label fw-semibold fs-6">Sorted server view</label>
                <div class="col-lg-8 d-flex align-items-center">
                    <div class="form-check form-check-solid form-switch form-check-custom fv-row">
                        <input class="form-check-input w-45px h-30px" type="checkbox" id="sortedServerView" @bind="UseSortedServerView">
                        <label class="form-check-label" for="sortedServerView"></label>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</LazyLoader>

@code
{
    [CascadingParameter]
    public User User { get; set; }

    private Server[] AllServers;
    private readonly Dictionary<Server, string> StatusCache = new();

    private bool UseSortedServerView = false;

    private Task Load(LazyLoader arg)
    {
        AllServers = ServerRepository
            .Get()
            .Include(x => x.Owner)
            .Include(x => x.MainAllocation)
            .Include(x => x.Node)
            .Include(x => x.Image)
            .Where(x => x.Owner.Id == User.Id)
            .OrderBy(x => x.Name)
            .ToArray();

        foreach (var server in AllServers)
        {
            Task.Run(async () =>
            {
                try
                {
                    using var scope = ServiceScopeFactory.CreateScope();
                    var serverService = scope.ServiceProvider.GetRequiredService<ServerService>();

                    AddStatus(server, (await serverService.GetDetails(server)).State);
                }
                catch (Exception e)
                {
                    AddStatus(server, "failed");
                }
            });
        }

        return Task.CompletedTask;
    }

    private void AddStatus(Server server, string status)
    {
        lock (StatusCache)
        {
            StatusCache.Add(server, status);
            InvokeAsync(StateHasChanged);
        }
    }
}