@page "/servers/create"
@using Moonlight.App.Services
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Forms
@using Moonlight.App.Models.Misc
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Exceptions

@inject SubscriptionService SubscriptionService
@inject ImageRepository ImageRepository
@inject SmartTranslateService SmartTranslateService
@inject SmartDeployService SmartDeployService
@inject ServerRepository ServerRepository
@inject NavigationManager NavigationManager
@inject ServerService ServerService

<LazyLoader Load="Load">
    @if (DeployNode == null)
    {
        <div class="d-flex justify-content-center flex-center">
            <div class="card">
                <img src="/assets/media/svg/nodata.svg" class="card-img-top w-25 mx-auto pt-5" alt="Not found image"/>
                <div class="card-body text-center">
                    <h4 class="card-title">
                        <TL>No node found</TL>
                    </h4>
                    <p class="card-text">
                        <TL>No node found to deploy to</TL>
                    </p>
                </div>
            </div>
        </div>
    }
    else
    {
        <div class="d-flex flex-column flex-lg-row">
            <div class="w-100 flex-lg-row-auto w-lg-300px mb-7 me-7 me-lg-10">
                <div class="card card-flush py-4">
                    <div class="card-header">
                        <div class="card-title">
                            <h2>
                                <TL>Server details</TL>
                            </h2>
                        </div>
                    </div>
                    <div class="card-body pt-0">
                        <div class="d-flex flex-column gap-10">
                            <div class="fv-row">
                                <label class="form-label"><TL>Node</TL></label>
                                <div class="fw-bold fs-3">@(DeployNode.Name)</div>
                            </div>
                            @if (Model.Image != null)
                            {
                                var limit = Images[Model.Image];

                                <div class="fv-row">
                                    <label class="form-label"><TL>Image</TL></label>
                                    <div class="fw-bold fs-3">@(Model.Image.Name)</div>
                                </div>

                                <div class="fv-row">
                                    <label class="form-label"><TL>CPU</TL></label>
                                    <div class="fw-bold fs-3">
                                        @{
                                            var cpu = limit.ReadValue("cpu");

                                            if (cpu == null)
                                                cpu = "N/A";
                                            else
                                                cpu = (int.Parse(cpu) / 100).ToString();
                                        }
                                        @(cpu) <TL>Cores</TL>
                                    </div>
                                </div>

                                <div class="fv-row">
                                    <label class="form-label"><TL>Memory</TL></label>
                                    <div class="fw-bold fs-3">@(limit.ReadValue("memory")) MB</div>
                                </div>

                                <div class="fv-row">
                                    <label class="form-label"><TL>Disk</TL></label>
                                    <div class="fw-bold fs-3">@(limit.ReadValue("disk")) MB</div>
                                </div>
                            }
                        </div>
                    </div>
                </div>
            </div>
            <div class="d-flex flex-column flex-lg-row-fluid gap-7 gap-lg-10">
                <div class="card card-flush py-4">
                    <div class="card-header">
                        <div class="card-title">
                            <h2>
                                <TL>Configure your server</TL>
                            </h2>
                        </div>
                    </div>
                    <div class="card-body pt-0">
                        <SmartForm Model="Model" OnValidSubmit="OnValidSubmit">
                            <label class="form-label">
                                <TL>Name</TL>
                            </label>
                            <div class="input-group mb-5">
                                <InputText @bind-Value="Model.Name" class="form-control"></InputText>
                            </div>
                            @if (Images.Any())
                            {
                                <label class="form-label">
                                    <TL>Image</TL>
                                </label>
                                <SmartSelect TField="Image"
                                             @bind-Value="Model.Image"
                                             Items="Images.Keys.ToArray()"
                                             DisplayField="@(x => x.Name)">
                                </SmartSelect>

                                <button type="submit" class="mt-5 float-end btn btn-primary">
                                    <TL>Create</TL>
                                </button>
                            }
                            else
                            {
                                <div class="alert alert-warning d-flex align-items-center p-5 mb-10">
                                    <span>
                                        <TL>You reached the maximum amount of servers for every image of your subscription</TL>: @(Subscription == null ? SmartTranslateService.Translate("Default") : Subscription.Name)
                                    </span>
                                </div>
                            }
                        </SmartForm>
                    </div>
                </div>
            </div>
        </div>
    }
</LazyLoader>

@code
{
    [CascadingParameter]
    public User User { get; set; }
    
    private Node? DeployNode;
    private Subscription? Subscription;

    private Dictionary<Image, SubscriptionLimit> Images = new();

    private ServerOrderDataModel Model = new();

    private async Task Load(LazyLoader lazyLoader)
    {
    // Reset state
        Images.Clear();
        Model = new();

        await lazyLoader.SetText(SmartTranslateService.Translate("Loading your subscription"));
        Subscription = await SubscriptionService.GetCurrent();

        await lazyLoader.SetText(SmartTranslateService.Translate("Searching for deploy node"));
        DeployNode = await SmartDeployService.GetNode();

        await lazyLoader.SetText(SmartTranslateService.Translate("Searching for available images"));
        var images = ImageRepository.Get().ToArray();

        foreach (var image in images)
        {
            var limit = await SubscriptionService.GetLimit("image." + image.Id);

            if (limit.Amount > 0)
            {
                var serversCount = ServerRepository
                    .Get()
                    .Include(x => x.Owner)
                    .Include(x => x.Image)
                    .Where(x => x.Owner.Id == User.Id)
                    .Count(x => x.Image.Id == image.Id);
                
                if(serversCount < limit.Amount)
                    Images.Add(image, limit);
            }
        }
    }

    private async Task OnValidSubmit()
    {
        var limit = await SubscriptionService.GetLimit("image." + Model.Image.Id);

        if (limit.Amount > 0)
        {
            var serversCount = ServerRepository
                .Get()
                .Include(x => x.Owner)
                .Include(x => x.Image)
                .Where(x => x.Owner.Id == User.Id)
                .Count(x => x.Image.Id == Model.Image.Id);

            if (serversCount < limit.Amount)
            {
                if(int.TryParse(limit.ReadValue("cpu"), out int cpu) &&
                    int.TryParse(limit.ReadValue("memory"), out int memory) &&
                    int.TryParse(limit.ReadValue("disk"), out int disk))
                {
                    var server = await ServerService.Create(
                        Model.Name,
                        cpu,
                        memory,
                        disk,
                        User,
                        Model.Image,
                        DeployNode,
                        null,
                        Model.Image.Allocations
                    );
                    
                    NavigationManager.NavigateTo($"/server/{server.Uuid}");
                }
                else
                {
                    throw new DisplayException("Limits cannot be parsed");
                }
            }
        }
    }
}