<?php
/**
 * POST /api/auth/reset
 *
 * Body: token, password, confirm_password
 *
 * Validates token from publisher_password_reset, updates password,
 * marks token used, kills all sessions for that user.
 */

declare(strict_types=1);
require_once dirname(__DIR__, 2) . '/config/bootstrap.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    jsonError('Method not allowed', 405);
}

$ip = Logger::clientIp();
RateLimit::hit('reset:ip:' . $ip, 10, 3600);

$token    = Validator::clean((string)($_POST['token'] ?? ''), 128);
$password = (string)($_POST['password'] ?? '');
$confirm  = (string)($_POST['confirm_password'] ?? $password);

if ($token === '' || strlen($token) !== 64 || !ctype_xdigit($token)) {
    jsonError('Invalid or malformed reset token.');
}
if (!Validator::password($password)) jsonError(Validator::passwordError());
if ($password !== $confirm) jsonError('Passwords do not match.');

$tokenHash = hash('sha256', $token);
$pdo = db();

$stmt = $pdo->prepare("
    SELECT id, publisher_id, expires_at, used
    FROM publisher_password_reset
    WHERE token_hash = ? LIMIT 1
");
$stmt->execute([$tokenHash]);
$row = $stmt->fetch();

if (!$row) {
    Logger::warning('Reset token not found', ['ip' => $ip]);
    jsonError('Invalid or expired reset link.', 404);
}
if ((int)$row['used'] === 1) {
    jsonError('This reset link has already been used.', 410);
}
if (strtotime((string)$row['expires_at']) < time()) {
    jsonError('This reset link has expired. Please request a new one.', 410);
}

$pdo->beginTransaction();
try {
    $newHash = password_hash($password, PASSWORD_ARGON2ID);
    $pdo->prepare("UPDATE publisher_user SET password_hash = ? WHERE id = ?")
        ->execute([$newHash, (int)$row['publisher_id']]);

    $pdo->prepare("UPDATE publisher_password_reset SET used = 1 WHERE id = ?")
        ->execute([(int)$row['id']]);

    // Force logout all existing sessions
    Session::destroyAllFor((int)$row['publisher_id']);

    $pdo->commit();
} catch (Throwable $e) {
    $pdo->rollBack();
    Logger::error('Password reset failed', ['error' => $e->getMessage()]);
    jsonError('Could not reset password. Please try again.', 500);
}

Logger::audit((int)$row['publisher_id'], 'password_reset_completed');
jsonSuccess('Password updated. Please log in with your new password.', [
    'redirect' => '/login',
]);
