<?php
declare(strict_types=1);

require_once __DIR__ . '/bootstrap.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/user_auth_lib.php';

header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'method'], JSON_UNESCAPED_UNICODE);
    exit;
}

mocker_require_csrf_post();

$uid = isset($_SESSION['mocker_user_id']) ? (int) $_SESSION['mocker_user_id'] : 0;
if ($uid <= 0) {
    http_response_code(401);
    echo json_encode(['ok' => false, 'error' => 'auth'], JSON_UNESCAPED_UNICODE);
    exit;
}

$input = json_decode((string) file_get_contents('php://input'), true) ?: [];
$newPassword = (string) ($input['newPassword'] ?? '');
$newPassword2 = (string) ($input['newPassword2'] ?? $input['password2'] ?? '');

if (strlen($newPassword) < 8) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'password'], JSON_UNESCAPED_UNICODE);
    exit;
}
if ($newPassword !== $newPassword2) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'mismatch'], JSON_UNESCAPED_UNICODE);
    exit;
}

try {
    $pdo = mocker_db();
} catch (Throwable $e) {
    http_response_code(503);
    echo json_encode(['ok' => false, 'error' => 'db'], JSON_UNESCAPED_UNICODE);
    exit;
}

mocker_user_auth_migrate($pdo);

$st = $pdo->prepare('SELECT ' . mocker_user_select_auth_columns() . ' FROM users WHERE id = :id LIMIT 1');
$st->execute([':id' => $uid]);
$row = $st->fetch(PDO::FETCH_ASSOC);

if (!$row) {
    unset($_SESSION['mocker_user_id']);
    http_response_code(401);
    echo json_encode(['ok' => false, 'error' => 'auth'], JSON_UNESCAPED_UNICODE);
    exit;
}

if (!mocker_user_needs_password_change($row)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'not_required'], JSON_UNESCAPED_UNICODE);
    exit;
}

$hash = password_hash($newPassword, PASSWORD_DEFAULT);
$upd = $pdo->prepare(
    'UPDATE users SET password_hash = :p, must_change_password = 0, password_imported = 1 WHERE id = :id'
);
$upd->execute([':p' => $hash, ':id' => $uid]);

$st->execute([':id' => $uid]);
$row = $st->fetch(PDO::FETCH_ASSOC);

echo json_encode(
    [
        'ok' => true,
        'user' => mocker_user_auth_payload($pdo, $row ?: []),
    ],
    JSON_UNESCAPED_UNICODE
);
