@page "/login"

@* This is just a "virtual" route/page. The handling for that is
@* MainLayout doing for us. We need to put that here so the router
@* does not return the 404 page
*@

@using Moonlight.App.Services.Interop
@using Moonlight.App.Services
@using Moonlight.App.Exceptions
@using Logging.Net
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Misc
@using Moonlight.App.Services.OAuth2
@using Moonlight.App.Services.Sessions
@using System.ComponentModel.DataAnnotations
@using Moonlight.App.Models.Forms

@inject AlertService AlertService
@inject UserService UserService
@inject SmartTranslateService SmartTranslateService
@inject CookieService CookieService
@inject NavigationManager NavigationManager
@inject GoogleOAuth2Service GoogleOAuth2Service
@inject DiscordOAuth2Service DiscordOAuth2Service

<div class="d-flex flex-center">
    <div class="card rounded-3 w-md-550px">
        <div class="card-body">
            <div class="d-flex flex-center flex-column-fluid pb-15 pb-lg-20">
                @if (!TotpRequired)
                {
                    <SmartForm Model="LoginData" OnValidSubmit="DoLogin">
                        <div class="text-center mt-3 mb-11">
                            <h1 class="text-dark fw-bolder mb-3">
                                <TL>Sign In</TL>
                            </h1>
                            <div class="text-gray-500 fw-semibold fs-6">
                                <TL>Sign in to start with moonlight</TL>
                            </div>
                        </div>

                        <div class="row g-3 mb-9">
                            <div class="col-md-6">
                                <a href="#" @onclick:preventDefault @onclick="DoDiscord" class="btn btn-flex btn-outline btn-text-gray-700 btn-active-color-primary bg-state-light flex-center text-nowrap w-100">
                                    <div class="h-15px me-3">
                                        <i class="mb-1 bx bx-md bxl-discord-alt"></i>
                                    </div>
                                    <TL>Sign in with Discord</TL>
                                </a>
                            </div>
                            <div class="col-md-6">
                                <a href="#" @onclick:preventDefault @onclick="DoGoogle" class="btn btn-flex btn-outline btn-text-gray-700 btn-active-color-primary bg-state-light flex-center text-nowrap w-100">
                                    <div class="h-15px me-3">
                                        <i class="mb-1 bx bx-md bxl-google"></i>
                                    </div>
                                    <TL>Sign in with Google</TL>
                                </a>
                            </div>
                        </div>

                        <div class="separator separator-content my-14">
                            <span class="w-125px text-gray-500 fw-semibold fs-7">
                                <TL>Or with email</TL>
                            </span>
                        </div>

                        <div class="mt-3 mb-3">
                            <InputText @bind-Value="LoginData.Email" type="email" placeholder="@(SmartTranslateService.Translate("Email"))" class="form-control bg-transparent"/>
                        </div>

                        <div class="mb-3">
                            <InputText @bind-Value="LoginData.Password" type="password" placeholder="@(SmartTranslateService.Translate("Password"))" class="form-control bg-transparent"/>
                        </div>

                        <div class="d-flex flex-stack flex-wrap gap-3 fs-base fw-semibold mb-8">
                            <div></div>

                            <a href="/passwordreset" class="link-primary">
                                <TL>Forgot password?</TL>
                            </a>
                        </div>

                        <div class="d-grid mb-10">
                            <button type="submit" class="btn btn-primary">
                                <TL>Sign-in</TL>
                            </button>
                        </div>

                        <div class="text-gray-500 text-center fw-semibold fs-6">
                            <TL>Not registered yet?</TL>

                            <a href="/register" class="link-primary">
                                <TL>Sign up</TL>
                            </a>
                        </div>
                    </SmartForm>
                }
                else
                {
                    <SmartForm Model="TotpData" OnValidSubmit="DoLogin">
                        <div class="fv-row mb-8 fv-plugins-icon-container">
                            <InputText @bind-Value="TotpData.Code" type="number" class="form-control bg-transparent"></InputText>
                        </div>
                        <div class="d-grid mb-10">
                            <button type="submit" class="btn btn-primary">
                                <TL>Sign-in</TL>
                            </button>
                        </div>
                    </SmartForm>
                }
            </div>
        </div>
    </div>
</div>

@code
{
    private LoginDataModel LoginData = new();
    private LoginTotpDataModel TotpData = new();

    private bool TotpRequired = false;

    private async Task DoLogin()
    {
        try
        {
            LoginData.Email = LoginData.Email.ToLower().Trim();

            if (string.IsNullOrEmpty(TotpData.Code))
            {
                TotpRequired = await UserService.CheckTotp(LoginData.Email, LoginData.Password);

                if (!TotpRequired)
                {
                    var token = await UserService.Login(LoginData.Email, LoginData.Password);
                    await CookieService.SetValue("token", token, 10);

                    if (NavigationManager.Uri.EndsWith("login"))
                        NavigationManager.NavigateTo("/", true);
                    else
                        NavigationManager.NavigateTo(NavigationManager.Uri, true);
                }
                else
                {
                    await InvokeAsync(StateHasChanged);
                }
            }
            else
            {
                var token = await UserService.Login(LoginData.Email, LoginData.Password, TotpData.Code);
                await CookieService.SetValue("token", token, 10);

                if (NavigationManager.Uri.EndsWith("login"))
                    NavigationManager.NavigateTo("/", true);
                else
                    NavigationManager.NavigateTo(NavigationManager.Uri, true);
            }
        }
        catch (DisplayException e)
        {
            // Reset state
            LoginData = new();
            TotpData = new();
            TotpRequired = false;
            
            await AlertService.Error(
                SmartTranslateService.Translate("Error"),
                SmartTranslateService.Translate(e.Message)
                );
        }
        catch (Exception e)
        {
            // Reset state
            LoginData = new();
            TotpData = new();
            TotpRequired = false;
            
            await AlertService.Error(
                SmartTranslateService.Translate("Error"),
                SmartTranslateService.Translate("An error occured while logging you in")
                );

            Logger.Error("Error while login");
            Logger.Error(e);
        }
    }

    private async Task DoGoogle()
    {
        var url = await GoogleOAuth2Service.GetUrl();
        NavigationManager.NavigateTo(url, true);
    }

    private async Task DoDiscord()
    {
        var url = await DiscordOAuth2Service.GetUrl();
        NavigationManager.NavigateTo(url, true);
    }
}