@model TwoFactorCodeViewModel
@{
    ViewData["Title"] = "Two-factor authentication";
}

<div class="page-heading compact auth-page-heading">
    <div>
        <p class="eyebrow">Account</p>
        <h1>Two-factor authentication</h1>
        <p class="lead-text">Enter the current 6-digit code from your authenticator app.</p>
    </div>
</div>

<section class="edit-panel two-factor-card">
    <form asp-action="TwoFactor" method="post" class="asset-create-form two-factor-body" data-two-factor-form>
        <input asp-for="ReturnUrl" type="hidden" />
        <input asp-for="Code" type="hidden" data-two-factor-code />
        <div asp-validation-summary="ModelOnly" class="alert alert-warning"></div>

        <div class="two-factor-code-group">
            <label class="form-label two-factor-label" for="twoFactorDigit1">Authenticator code</label>
            <div class="two-factor-inputs" role="group" aria-label="Authenticator code">
                @for (var i = 1; i <= 6; i++)
                {
                    <input class="form-control two-factor-digit"
                           id="twoFactorDigit@(i)"
                           type="text"
                           inputmode="numeric"
                           pattern="[0-9]*"
                           maxlength="1"
                           autocomplete="one-time-code"
                           aria-label="Digit @i of 6"
                           data-two-factor-digit />
                }
            </div>
            <span class="text-danger" asp-validation-for="Code"></span>
        </div>

        <div class="two-factor-actions">
            <button class="btn btn-primary" type="submit">Continue</button>
            <a class="btn btn-outline-secondary" asp-action="Login">Back to Login</a>
        </div>
        <p class="two-factor-help">
            <span>Can't access your authenticator app?</span>
            <a asp-action="TwoFactorRecovery" asp-route-returnUrl="@Model.ReturnUrl">Use a recovery code.</a>
        </p>
    </form>
</section>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
    <script>
        (() => {
            const form = document.querySelector("[data-two-factor-form]");
            if (!form) {
                return;
            }

            const hiddenCode = form.querySelector("[data-two-factor-code]");
            const digits = Array.from(form.querySelectorAll("[data-two-factor-digit]"));
            let hasSubmitted = false;

            const codeValue = () => digits.map(input => input.value).join("");
            const syncCode = () => {
                hiddenCode.value = codeValue();
            };
            const isComplete = () => digits.every(input => input.value.length === 1);
            const submitIfComplete = () => {
                syncCode();
                if (isComplete() && !hasSubmitted) {
                    hasSubmitted = true;
                    form.requestSubmit();
                }
            };
            const fillFrom = (startIndex, value) => {
                const numbers = value.replace(/\D/g, "").slice(0, digits.length - startIndex);
                numbers.split("").forEach((number, offset) => {
                    digits[startIndex + offset].value = number;
                });

                const nextIndex = Math.min(startIndex + numbers.length, digits.length - 1);
                digits[nextIndex].focus();
                submitIfComplete();
            };

            digits.forEach((input, index) => {
                input.addEventListener("input", () => {
                    if (input.value.length > 1) {
                        fillFrom(index, input.value);
                        return;
                    }

                    input.value = input.value.replace(/\D/g, "");
                    syncCode();

                    if (input.value && index < digits.length - 1) {
                        digits[index + 1].focus();
                    }

                    submitIfComplete();
                });

                input.addEventListener("keydown", event => {
                    if (event.key === "Backspace" && !input.value && index > 0) {
                        digits[index - 1].focus();
                        digits[index - 1].value = "";
                        syncCode();
                    }
                });

                input.addEventListener("paste", event => {
                    event.preventDefault();
                    fillFrom(index, event.clipboardData.getData("text"));
                });

                input.addEventListener("focus", () => input.select());
            });

            form.addEventListener("submit", () => {
                syncCode();
            });

            digits.forEach(input => {
                input.value = "";
            });
            syncCode();
            digits[0].focus();
        })();
    </script>
}
