<?php
require_once __DIR__.'/../app/bootstrap.php';
use App\Core\Auth;use App\Core\Database;use App\Core\Response;use App\Core\Security;
Auth::requireLogin('public/login.php');
if($_SERVER['REQUEST_METHOD']!=='POST'||!verify_csrf())Response::json(['ok'=>false,'message'=>'Invalid request.'],419);
$d=request_data();$purpose=preg_replace('/[^a-z0-9_-]/i','',(string)($d['purpose']??'security'))?:'security';
if(!Security::rateLimit('otp-verify:'.Auth::id().'|'.$purpose,8,600))Response::json(['ok'=>false,'message'=>'Too many invalid OTP attempts. Request a new code.'],429);
$row=Database::safeFetchOne('SELECT * FROM otp_verifications WHERE user_id=? AND purpose=? AND verified_at IS NULL AND expires_at>NOW() ORDER BY id DESC LIMIT 1',[Auth::id(),$purpose]);
if(!$row||!password_verify((string)($d['otp']??''),(string)$row['otp_code']))Response::json(['ok'=>false,'message'=>'Invalid or expired OTP.'],422);
Database::execute('UPDATE otp_verifications SET verified_at=NOW() WHERE id=?',[$row['id']]);
Security::clearRateLimit('otp-verify:'.Auth::id().'|'.$purpose);
$_SESSION['otp_verified'][$purpose]=time();
Security::logActivity(Auth::id(),'otp_verified',['purpose'=>$purpose]);
Response::json(['ok'=>true,'message'=>'OTP verified.']);
