<?php
// reset-otp-check.php — Server-side POST handler for the password-reset OTP step.
//
// reset-password-verify.php submits the 6-digit code here as a normal HTML
// form POST (not AJAX). We verify the code, set the session vars, and redirect
// — all in ONE request so there is no cross-request session-cookie problem.
//
// On success  → Location: reset-password.php
// On error    → Location: reset-password-verify.php?email=... (with flash)

session_start();
require_once __DIR__ . '/config/db.php';

const OTP_MAX_ATTEMPTS = 5;

/**
 * Redirect back to the verify page with an error flash.
 */
function otp_error(string $email, string $msg): never
{
    $_SESSION['otp_error'] = $msg;
    header('Location: reset-password-verify.php?email=' . urlencode($email));
    exit;
}

// Only POST is accepted.
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: forgot-password.php');
    exit;
}

$email   = trim($_POST['email']    ?? '');
$otpCode = trim($_POST['otp_code'] ?? '');

// Basic validation.
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    header('Location: forgot-password.php');
    exit;
}

if (!preg_match('/^\d{6}$/', $otpCode)) {
    otp_error($email, 'Please enter the complete 6-digit code.');
}

// Fetch the most recent, unused code for this email + purpose.
try {
    $stmt = $pdo->prepare(
        'SELECT id, otp_code, attempts, expires_at, is_used
         FROM otp_codes
         WHERE email = :email AND purpose = :purpose
         ORDER BY created_at DESC LIMIT 1'
    );
    $stmt->execute(['email' => $email, 'purpose' => 'password_reset']);
    $row = $stmt->fetch();
} catch (PDOException $e) {
    otp_error($email, 'Something went wrong. Please try again.');
}

if (!$row) {
    otp_error($email, 'No reset code found for this email. Please request a new one.');
}

if ((int) $row['is_used'] === 1) {
    otp_error($email, 'This code has already been used. Please request a new one.');
}

if (strtotime($row['expires_at']) < time()) {
    otp_error($email, 'This code has expired. Please request a new one.');
}

if ((int) $row['attempts'] >= OTP_MAX_ATTEMPTS) {
    otp_error($email, 'Too many incorrect attempts. Please request a new code.');
}

if (!hash_equals($row['otp_code'], $otpCode)) {
    // Increment attempt counter.
    try {
        $upd = $pdo->prepare('UPDATE otp_codes SET attempts = attempts + 1 WHERE id = :id');
        $upd->execute(['id' => $row['id']]);
    } catch (PDOException $e) { /* non-fatal */ }

    $remaining = OTP_MAX_ATTEMPTS - ((int) $row['attempts'] + 1);
    otp_error($email, 'Incorrect code. ' . max($remaining, 0) . ' attempt(s) remaining.');
}

// ── SUCCESS ──────────────────────────────────────────────────────────────────
// Mark the OTP as used so it can't be replayed.
try {
    $upd = $pdo->prepare('UPDATE otp_codes SET is_used = 1 WHERE id = :id');
    $upd->execute(['id' => $row['id']]);
} catch (PDOException $e) { /* non-fatal — the time expiry is the safety net */ }

// Store verified state in session.  This happens in the SAME request as the
// redirect, so there is no cross-request session-cookie timing issue.
$_SESSION['reset_email']          = $email;
$_SESSION['reset_email_verified'] = true;

header('Location: reset-password.php');
exit;
