<script lang="ts">
    import {onMount} from "svelte";
    import {enforce_session} from "$lib/auth";
    import {Logger, logSetup} from "$lib/logger";
    import {get_user_info} from "$lib/auth";
    import type {UserInfo} from "$lib/auth";
    import {t} from "$lib/i18n";
    import {validateTOTP} from "$lib/totp";
    import {setCookie} from "$lib/cookie";
    import {enforce_auth} from "$lib/auth";
    
    let logger = new Logger("auth/mfa/+page.svelte");
    logSetup();
    
    let isFinished = false;
    let isloading = false;
    let api_token = "";
    let mfa_token = "";
    let hasError = false;
    let error = "";

    onMount(async () => {
        let st_res = await enforce_session();
        if (!st_res[0]) {
            // session token is invalid
            // Session token is invalid. redirect to login
            logger.info("Invalid session token, redirecting to login");
            window.location = "/auth/login";
            return;
        }
        api_token = st_res[1];

        let at_res = await enforce_auth();
        if (at_res[0]) {
            logger.info("User already TOTP authenticated");
            window.location = "/admin";
            return;
        }

        let user: UserInfo | string = await get_user_info(api_token);
        if (typeof user === "string") {
            logger.error(`Unable to get user info: ${user}`);
            hasError = true;
            error = user;
            return;
        }

        if (!user.data.actor.hasTOTPAuthenticator) {
            logger.error('User doesn\'t have MFA setup yet, redirecting');
            window.location = "/auth/mfasetup";
            return;
        }
    });

    async function tryMFACode() {
        isloading = true;
        logger.info(`Submitting 2FA verify with code ${mfa_token}`);
        let resp = await validateTOTP(api_token, mfa_token);
        if (typeof resp === "string") {
            logger.error(`Unable to validate TOTP token: ${resp}`);
            hasError = true;
            isloading = false;
            error = t(`mfa.apierror.${resp}`);
            return;
        }
        // set cookie
        setCookie("authToken", resp.token, 86400 * 365);
        window.location = "/admin";
    }

    function validateKeypress(e: KeyboardEvent) {
        if (e.charCode === 13) { return; }
        if (e.charCode < 47 || e.charCode > 57) {
            e.preventDefault();
        }
        if (e.target.value.length >= 6) {
            e.preventDefault();
        }
    }
</script>


<div class="flex in-h-full items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
    <div class="w-full max-w-md">
        {#if !isFinished}
            <!-- Title -->
            <div>
                <h1 class="font-semibold text-2xl">{t('mfa.title')}</h1>
                <h2 class="ftext-sm">{t('mfa.subtitle')}</h2>
            </div>

            <!-- The actual form -->
            <form class="mt-5" action="#" method="POST" on:submit|preventDefault={tryMFACode}>
                <div class="-space-y-px rounded-md shadow-sm">
                    <label for="mfa_token" class="sr-only">{t('mfa.prompt')}</label>
                    <input on:keypress={validateKeypress} bind:value={mfa_token} type="number" maxlength="6" id="mfa_token"
                           class="dark:bg-slate-500 bg-gray-200 w-full rounded px-3 py-2 focus:outline-none focus:ring-purple-500 appearance-none">
                    {#if hasError}
                        <span class="text-red-600 text-sm">{error}</span>
                    {/if}
                </div>

                <button class="bg-purple-400 dark:bg-purple-600 mt-4 w-full py-2 -space-y-px rounded-md shadow-sm place-content-center">
                    {#if !isloading}
                        {t('mfa.actionButtonText')}
                    {:else}
                        <svg class="animate-spin w-5 h-5 inline-block m-auto" xmlns="http://www.w3.org/2000/svg"
                             fill="none" viewBox="0 0 24 24">
                            <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor"
                                    stroke-width="4"></circle>
                            <path class="opacity-75" fill="currentColor"
                                  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                        </svg>
                    {/if}
                </button>
            </form>
        {:else}
            <!-- Title -->
            <div>
                <h1 class="font-semibold text-2xl">{t('mfa.done')}</h1>
                <h2 class="ftext-sm">{t('mfa.doneSubtitle')}</h2>
            </div>
        {/if}
    </div>
</div>