@page "/Servers/{id:guid}"
@page "/Servers/{id:guid}/{panel}"
@page "/Servers/{id:guid}/{panel}/{logId}"
@page "/Servers/Add"
@attribute [Authorize(Roles = "Administrator")]
@using LANCommander.Components.FileManagerComponents;
@using LANCommander.Pages.Servers.Components
@inject GameService GameService
@inject ServerService ServerService
@inject ServerProcessService ServerProcessService
@inject IMessageService MessageService
@inject NavigationManager NavigationManager

<Layout Class="panel-layout" Style="padding: 24px 0;">
    <Sider Width="200">
        <Menu Mode="@MenuMode.Inline" Style="height: 100%;">
            <MenuItem RouterLink="@($"/Servers/{Server.Id}/General")">General</MenuItem>
            <MenuItem RouterLink="@($"/Servers/{Server.Id}/HTTP")">HTTP</MenuItem>
            @if (Server != null && Server.Id != Guid.Empty)
            {
                <MenuItem RouterLink="@($"/Servers/{Server.Id}/Consoles")">Consoles</MenuItem>
                <SubMenu Key="Monitor" Title="Monitor" Disabled="@(Server.ServerConsoles == null || Server.ServerConsoles.Count == 0)">
                    @if (!Server.UseShellExecute)
                    {
                        <MenuItem Key="Console" RouterLink="@($"/Servers/{Server.Id}/Monitor/Console")">Console</MenuItem>
                    }

                    @if (Server.ServerConsoles != null && Server.ServerConsoles.Any(c => c.Id != Guid.Empty))
                    {
                        foreach (var log in Server.ServerConsoles.Where(c => c.Id != Guid.Empty))
                        {
                            <MenuItem Key="@log.Id.ToString()" RouterLink="@($"/Servers/{Server.Id}/Monitor/{log.Id}")">@log.Name</MenuItem>
                        }
                    }
                </SubMenu>
                <MenuItem RouterLink="@($"/Servers/{Server.Id}/Files")">Files</MenuItem>
            }
        </Menu>
    </Sider>

    <Content>
        <PageHeader>
            <PageHeaderTitle>@Panel</PageHeaderTitle>
            <PageHeaderExtra>
                @if (Server.Id != Guid.Empty)
                {
                    <ServerControl ServerId="Id" />
                }
            </PageHeaderExtra>
        </PageHeader>


        <div class="panel-layout-content">
            @if (Panel == "General" || String.IsNullOrWhiteSpace(Panel))
            {
                <Form Model="@Server" Layout="@FormLayout.Vertical">
                    <FormItem Label="Name">
                        <Input @bind-Value="@context.Name" />
                    </FormItem>
                    <FormItem Label="Game">
                        <Select TItem="Game"
                                TItemValue="Guid"
                                DataSource="@Games.OrderBy(g => String.IsNullOrWhiteSpace(g.SortTitle) ? g.Title : g.SortTitle)"
                        @bind-Value="@GameId"
                                LabelName="Title"
                                ValueName="Id"
                                Placeholder="Select a Game"
                                DefaultActiveFirstOption="false"
                                EnableSearch>
                                <ItemTemplate Context="game">
                                    <Image Src="@GetIcon(game)" Height="32" Width="32" Preview="false"></Image>
                                    @game.Title
                                </ItemTemplate>
                        </Select>
                    </FormItem>
                    <FormItem Label="Path">
                        <FilePicker Root="@RootPath" EntrySelectable="x => x is FileManagerFile" @bind-Value="@context.Path" OnSelected="OnPathSelected" />
                    </FormItem>
                    <FormItem Label="Arguments">
                        <Input @bind-Value="@context.Arguments" />
                    </FormItem>
                    <FormItem Label="Working Directory">
                        <FilePicker Root="@RootPath" Title="Choose Working Directory" OkText="Select Directory" EntrySelectable="x => x is FileManagerDirectory" @bind-Value="@context.WorkingDirectory" />
                    </FormItem>
                    <FormItem>
                        <LabelTemplate>
                            Use Shell Execute
                            <Tooltip Title="This option specifies whether you would like to run the server using the shell. Some servers may require this as they will have a UI or won't output logs to stdout">
                                <Icon Type="@IconType.Outline.QuestionCircle" Theme="@IconThemeType.Outline" />
                            </Tooltip>
                        </LabelTemplate>
                        <ChildContent>
                            <Switch @bind-Checked="context.UseShellExecute" />
                        </ChildContent>
                    </FormItem>
                    <GridRow Wrap="false" Gutter="16">
                        <GridCol Flex="@("none")">
                            <FormItem Label="Autostart">
                                <Switch @bind-Checked="context.Autostart" />
                            </FormItem>
                        </GridCol>
                        <GridCol Flex="@("auto")">
                            @if (context.Autostart)
                            {
                                <FormItem Label="Delay">
                                    <AntDesign.Input @bind-Value="context.AutostartDelay" Placeholder="0">
                                        <Suffix>Seconds</Suffix>
                                    </AntDesign.Input>
                                </FormItem>
                            }
                        </GridCol>
                    </GridRow>

                    <FormItem>
                        <Button Type="@ButtonType.Primary" OnClick="Save" Icon="@IconType.Fill.Save">Save</Button>
                    </FormItem>
                </Form>
            }

            @if (Panel == "HTTP")
            {
                <Text>HTTP paths are a way to host static files such as maps and other assets. Engines such as Source, id Tech 3, and Unreal can utilize HTTP for faster downloads when connecting to a server.</Text>
                <ServerHttpPathEditor @bind-Values="Server.HttpPaths" ServerId="Id" WorkingDirectory="@Server.WorkingDirectory" />

                <Button Type="@ButtonType.Primary" OnClick="Save" Icon="@IconType.Fill.Save">Save</Button>                
            }

            @if (Panel == "Consoles")
            {
                <ServerConsoleEditor @bind-Value="Server.ServerConsoles" ServerId="Id" />

                <Button Type="@ButtonType.Primary" OnClick="Save" Icon="@IconType.Fill.Save">Save</Button>
            }

            @if (Panel == "Monitor")
            {
                @if (LogId == "Console") {
                    <Console ServerId="@Server.Id" />
                }
                else if (LogId != null && LogId != Guid.Empty.ToString())
                {
                    <Console ServerId="@Server.Id" ServerConsoleId="@Guid.Parse(LogId)" />
                }
                else
                {
                    <ServerConsoleEditor @bind-Value="Server.ServerConsoles" ServerId="Id" />

                    <Button Type="@ButtonType.Primary" OnClick="Save" Icon="@IconType.Fill.Save">Save</Button>
                }
            }

            @if (Panel == "Files")
            {
                <TextEditor WorkingDirectory="@Server.WorkingDirectory" />
            }
        </div>
    </Content>
</Layout>

@code {
    [Parameter] public Guid Id { get; set; }
    [Parameter] public string Panel { get; set; }
    [Parameter] public string LogId { get; set; }

    IEnumerable<Game> Games = new List<Game>();

    string RootPath = Path.GetPathRoot(Directory.GetCurrentDirectory());

    Server Server;
    Guid GameId;

    protected override async Task OnInitializedAsync()
    {
        if (Id == Guid.Empty)
            Server = new Server();
        else
            Server = await ServerService.Get(Id);

        if (Server.GameId.HasValue)
            GameId = Server.GameId.Value;

        if (Server.HttpPaths == null)
            Server.HttpPaths = new List<ServerHttpPath>();

        Games = await GameService.Get();
    }

    private async Task Save()
    {
        try
        {
            Server.GameId = GameId;

            if (Server.Id != Guid.Empty)
            {
                Server = await ServerService.Update(Server);

                await MessageService.Success("Server updated!");
            }
            else
            {
                Server = await ServerService.Add(Server);

                NavigationManager.LocationChanged += NotifyServerAdded;

                NavigationManager.NavigateTo($"/Servers/{Server.Id}");
            }
        }
        catch (Exception ex)
        {
            await MessageService.Error("Could not save!");
        }
    }

    private async Task AddPath()
    {
        Server.HttpPaths.Add(new ServerHttpPath()
        {
            ServerId = Server.Id
        });
    }

    private void OnPathSelected(string path)
    {
        Server.WorkingDirectory = Path.GetDirectoryName(path);
    }

    private void NotifyServerAdded(object? sender, LocationChangedEventArgs e)
    {
        NavigationManager.LocationChanged -= NotifyServerAdded;

        MessageService.Success("Server added!");
    }

    private string GetIcon(Game game)
    {
        var media = game?.Media?.FirstOrDefault(m => m.Type == Data.Enums.MediaType.Icon);

        if (media != null)
            return $"/api/Media/{media.Id}/Download?fileId={media.FileId}";
        else
            return "/favicon.ico";
    }
}