<?php
// =============================================================
//  POST /api/v1/auth/setup_2fa_confirm
//
//  Mobile equivalent of app/setup_2fa.php's 'confirm_enable' action.
//  Body: { "secret": "...", "code": "123456" } — the secret is the one
//  setup_2fa_start.php just returned (round-tripped through the client
//  rather than a $_SESSION value; see that endpoint's own doc comment
//  for why). Verifying a real code from the account holder's
//  authenticator app before saving anything is exactly what the
//  desktop flow does too — a mis-scanned/mis-typed secret can never
//  silently lock someone out, since it's never persisted unless a
//  real code against it is proven first.
//
//  On success, returns the eight recovery codes in plain text exactly
//  once — the client must show these immediately and permanently,
//  same as the desktop page's own "Save these recovery codes now"
//  warning; only their bcrypt hashes are stored.
// =============================================================

require_once __DIR__ . '/../_bootstrap.php';
require_once __DIR__ . '/../../../include/Totp.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    Api::error(405, 'MethodNotAllowed', 'Use POST');
}

$account = api_authenticate();
api_require_staff_role($account, ['Admin', 'Chief_Preceptor', 'Preceptor', 'Nurse_Manager', 'In_Charge']);

if (!Totp::columnsExist($conn)) {
    Api::error(503, 'NotConfigured', 'Two-factor authentication is not set up on this server yet.');
}
if (Totp::isEnabledFor($conn, $account->getId())) {
    Api::error(409, 'AlreadyEnabled', 'Two-factor authentication is already enabled for this account.');
}

$body   = Api::body();
$secret = trim((string)($body['secret'] ?? ''));
$code   = trim((string)($body['code'] ?? ''));

if ($secret === '') {
    Api::error(422, 'ValidationError', 'secret is required');
}
if ($code === '') {
    Api::error(422, 'ValidationError', 'code is required');
}
if (!Totp::verifyCode($secret, $code)) {
    Api::error(401, 'InvalidCode', 'That code did not match. Double-check your authenticator app and try again.');
}

$codes  = Totp::generateRecoveryCodes(8);
$hashed = array_map(fn($c) => password_hash($c, PASSWORD_DEFAULT), $codes);

$userId = $account->getId();
$stmt = $conn->prepare('UPDATE users SET totp_secret = ?, totp_enabled = 1, totp_recovery_codes = ? WHERE id = ?');
$json = json_encode($hashed);
$stmt->bind_param('ssi', $secret, $json, $userId);
$stmt->execute();
$stmt->close();

$perm_manager->logAudit($userId, 'enable_2fa', 'user', $userId, null, null);

Api::success(['recovery_codes' => $codes]);
