<?php
/**
 * /api/user/profile — Logged-in user self-service.
 *
 * Lets a regular user change their own username and/or password
 * (admin credentials remain manageable only via config.php / admin panel).
 *
 * PUT body:
 *   { current_password: required,
 *     new_username?:   string (3–32),
 *     new_password?:   string (4–128) }
 *
 * Returns: { access_token, token_type, user }   (new JWT re-issued)
 */

function route_user_update_profile(): void {
    $user = require_auth();
    if (($user['role'] ?? '') === 'admin') {
        json_error(403, 'Admin credentials must be changed via config.php');
    }

    $b = read_json_body();
    $current = require_field($b, 'current_password');

    $row = db()->prepare('SELECT password_hash FROM users WHERE id = ?');
    $row->execute([$user['id']]);
    $creds = $row->fetch();
    if (!$creds || !password_verify($current, $creds['password_hash'])) {
        json_error(401, 'Current password is incorrect');
    }

    $new_username_raw = isset($b['new_username']) ? trim((string)$b['new_username']) : '';
    $new_password     = isset($b['new_password']) ? (string)$b['new_password']       : '';
    $new_username     = strtolower($new_username_raw);

    $updates = [];
    $params  = [];
    if ($new_username !== '' && $new_username !== $user['username']) {
        if (strlen($new_username) < 3 || strlen($new_username) > 32) {
            json_error(400, 'new_username must be 3-32 characters');
        }
        $check = db()->prepare('SELECT 1 FROM users WHERE username = ? AND id <> ?');
        $check->execute([$new_username, $user['id']]);
        if ($check->fetch()) json_error(409, 'Username already taken');
        $updates[] = 'username = ?';
        $params[]  = $new_username;
    }
    if ($new_password !== '') {
        if (strlen($new_password) < 4 || strlen($new_password) > 128) {
            json_error(400, 'new_password must be 4-128 characters');
        }
        $updates[] = 'password_hash = ?';
        $params[]  = password_hash($new_password, PASSWORD_BCRYPT);
    }

    if (empty($updates)) json_error(400, 'Nothing to update');

    $params[] = $user['id'];
    $sql = 'UPDATE users SET ' . implode(', ', $updates) . ' WHERE id = ?';
    db()->prepare($sql)->execute($params);

    $fresh = db()->prepare('SELECT * FROM users WHERE id = ?');
    $fresh->execute([$user['id']]);
    $shaped = shape_user($fresh->fetch());
    $token  = make_access_token([
        'id' => $shaped['id'], 'username' => $shaped['username'], 'role' => $shaped['role'],
    ]);

    send_json([
        'access_token' => $token,
        'token_type'   => 'bearer',
        'user'         => $shaped,
    ]);
}
