<?php

$path = '../../';
$noauth = true;
require_once $path . 'core/includes/header.inc.php';

use Mtc\Core\Admin\TotpService;
use Mtc\Core\RateLimit;

$adminuser = new AdminUser();

// Already fully authenticated — go to admin
if (!empty($_SESSION['adminId']) && $_SESSION['adminId'] > 0) {
    header('Location: /admin');
    exit();
}

// Must have a pending 2FA session
if (empty($_SESSION['admin_2fa_pending_id'])) {
    header('Location: /admin/login.php');
    exit();
}

// Pending session expires after 5 minutes
if (empty($_SESSION['admin_2fa_pending_at']) || (time() - $_SESSION['admin_2fa_pending_at']) > 300) {
    unset($_SESSION['admin_2fa_pending_id'], $_SESSION['admin_2fa_pending_at'], $_SESSION['admin_2fa_setup_secret']);
    header('Location: /admin/login.php');
    exit();
}

$errors = [];
$locked = false;
$page_meta['title'] = 'Set Up Two-Factor Authentication';
$pendingId = (int) $_SESSION['admin_2fa_pending_id'];
$adminUser = \Mtc\Core\AdminUser::query()->find($pendingId);
$rateLimitKey = '2fa_setup_' . $pendingId;
$maxAttempts = 5;
$lockoutSeconds = 120;

if (!$adminUser) {
    unset($_SESSION['admin_2fa_pending_id'], $_SESSION['admin_2fa_pending_at'], $_SESSION['admin_2fa_setup_secret']);
    header('Location: /admin/login.php');
    exit();
}

$service = new TotpService();

// Generate a new secret only on first visit — reuse across reloads
if (empty($_SESSION['admin_2fa_setup_secret'])) {
    $_SESSION['admin_2fa_setup_secret'] = $service->generateSecret();
}
$pendingSecret = $_SESSION['admin_2fa_setup_secret'];

// Check if already rate limited (account-level, ignores IP)
if (RateLimit::isLocked($rateLimitKey, $lockoutSeconds, $maxAttempts)) {
    $locked = true;
    $timeRemaining = RateLimit::getTimeRemaining($rateLimitKey, $lockoutSeconds, true);
    $minutes = max(1, ceil($timeRemaining / 60));
    $errors[] = 'Too many failed attempts. Please wait ' . $minutes . ' minute' . ($minutes > 1 ? 's' : '') . ' before trying again.';
}

if (!$locked && isset($_POST['setup_2fa'])) {
    if (!CSRF::checkToken('admin_2fa_setup')) {
        $errors[] = 'Setup failed, please try again.';
    }

    $code = preg_replace('/\s+/', '', $_POST['totp_code'] ?? '');

    if (empty($code)) {
        $errors[] = 'Please enter the verification code from your app.';
    }

    if (empty($errors)) {
        $timestamp = $service->verifyCode($pendingSecret, $code);

        if ($timestamp !== false) {
            // Save the secret and timestamp to the user record (forceFill bypasses $fillable intentionally)
            $adminUser->forceFill(['totp_secret' => $pendingSecret, 'totp_last_used_at' => $timestamp])->save();

            // Promote to full session
            unset($_SESSION['admin_2fa_pending_id']);
            unset($_SESSION['admin_2fa_pending_at']);
            unset($_SESSION['admin_2fa_setup_secret']);
            session_regenerate_id(true);
            $_SESSION['adminId'] = $pendingId;
            $_SESSION['mtcadminarea'] = true;
            \Mtc\Core\AdminUser::query()
                ->where('id', $pendingId)
                ->update(['session_id' => session_id()]);

            header('Location: /admin/index.php');
            exit();
        } else {
            // Log failed attempt (account-level, ignores IP)
            RateLimit::logAttempt($rateLimitKey);

            if (RateLimit::isLocked($rateLimitKey, $lockoutSeconds, $maxAttempts)) {
                $locked = true;
                unset($_SESSION['admin_2fa_setup_secret']);
                $errors[] = 'Too many failed attempts. Please wait 2 minutes before trying again.';
            } else {
                $remaining = $maxAttempts - RateLimit::where('key', $rateLimitKey)
                    ->where('created_at', '>=', now()->subSeconds($lockoutSeconds))
                    ->count();
                $errors[] = 'Invalid code. ' . $remaining . ' attempt' . ($remaining !== 1 ? 's' : '') . ' remaining.';
            }
        }
    }
}

$qrSvg = $service->getQrCodeSvg($pendingSecret, $adminUser->email ?: $adminUser->username);
// Format the secret in groups of 4 for readability
$formattedSecret = implode(' ', str_split($pendingSecret, 4));

require_once $path . 'core/admin/templates/adminheader.html.php';
?>

<div class="tfa-container">
    <div class="tfa-card tfa-setup-card">
        <div class="tfa-icon">
            <i class="fa fa-shield"></i>
        </div>
        <h1>Set Up Two-Factor Authentication</h1>

        <?php
        if (!empty($errors)) {
            showerrors($errors);
        }
        ?>

        <div class="tfa-setup-top">
            <div class="tfa-setup-qr">
                <div class="tfa-qr-wrapper">
                    <?= $qrSvg ?>
                </div>
                <div class="tfa-manual-key">
                    <span>Can't scan? Enter this key manually:</span>
                    <code class="tfa-secret-display"><?= clean_page($formattedSecret) ?></code>
                </div>
            </div>
            <ol class="tfa-setup-instructions">
                <li>Open your authenticator app (Google Authenticator, Authy, etc.)</li>
                <li>Scan the QR code or enter the key</li>
                <li>Enter the 6-digit code below to confirm</li>
            </ol>
        </div>

        <div class="tfa-setup-divider"></div>

        <form action="2fa_setup.php" method="post" id="tfaForm">
            <div class="tfa-setup-confirm">
                <div class="tfa-digits" id="tfaDigits">
                    <input type="text" class="tfa-digit" data-index="0" inputmode="numeric" maxlength="1" autocomplete="off" autofocus />
                    <input type="text" class="tfa-digit" data-index="1" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="2" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <div class="tfa-digit-separator"></div>
                    <input type="text" class="tfa-digit" data-index="3" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="4" inputmode="numeric" maxlength="1" autocomplete="off" />
                    <input type="text" class="tfa-digit" data-index="5" inputmode="numeric" maxlength="1" autocomplete="off" />
                </div>
                <input type="hidden" name="totp_code" id="totp_code" value="" />
                <?= CSRF::token('admin_2fa_setup') ?>
                <input type="hidden" name="setup_2fa" value="1" />
            </div>
        </form>
    </div>
</div>

<?php
require_once $path . 'core/admin/templates/adminfooter.html.php';
