<?php
// ============================================================
//  MediCore — Staff Self-Service Profile API
//  File: api/profile.php
//
//  Scoped ALWAYS to the logged-in user via current_user_id() — every
//  action below ignores any "id" the client might send, so this
//  endpoint can never be used to view/edit/reset another account.
//  Admin-wide user management (add/edit/delete OTHER users, roles,
//  permissions) stays exactly where it already lives, in
//  api/settings.php + require_admin().
// ============================================================
require_once '../includes/db.php';
require_once '../includes/auth.php';
require_once '../includes/audit.php';
require_login();

header('Content-Type: application/json');

$body   = json_decode(file_get_contents('php://input'), true) ?? [];
$action = trim($body['action'] ?? '');

try {
    match ($action) {
        'me'              => api_me(),
        'update_profile'  => api_update_profile($body),
        'change_password' => api_change_password($body),
        default           => fail('Unknown action'),
    };
} catch (Throwable $e) {
    fail($e->getMessage());
}

// ── Current user's own profile ──────────────────────────────────
function api_me(): void {
    ensure_users_photo_column();
    $id = current_user_id();
    $u  = db_row(
        "SELECT id, name, username, role, avatar, photo, created_at FROM users WHERE id = ?",
        [$id]
    );
    if (!$u) fail('User not found.');
    ok(['data' => $u]);
}

// ── Update own name / username / photo ────────────────────────────
function api_update_profile(array $b): void {
    ensure_users_photo_column();
    $id = current_user_id();

    $name     = trim($b['name']     ?? '');
    $username = trim($b['username'] ?? '');
    if ($name === '')     fail('Name is required.');
    if ($username === '') fail('Username is required.');
    if (!preg_match('/^[a-zA-Z0-9_.]{3,60}$/', $username)) {
        fail('Username may only contain letters, numbers, dot and underscore (3–60 characters).');
    }
    if (db_val("SELECT id FROM users WHERE username = ? AND id != ?", [$username, $id])) {
        fail("Username \"$username\" is already taken.");
    }

    $words  = preg_split('/\s+/', $name, -1, PREG_SPLIT_NO_EMPTY);
    $avatar = strtoupper(substr($words[0] ?? '', 0, 1) . substr($words[1] ?? '', 0, 1));

    $sql    = "UPDATE users SET name = ?, username = ?, avatar = ?";
    $params = [$name, $username, $avatar];

    // Photo arrives as a base64 data-URI from the browser's FileReader —
    // same client-side pattern already used by Settings > Logo and the
    // customer portal's profile picture (shop/profile.php); this app has
    // no server-side file-upload/storage mechanism anywhere.
    if (array_key_exists('photo', $b)) {
        $photo = trim((string) $b['photo']);
        if ($photo !== '' && !str_starts_with($photo, 'data:image/')) {
            fail('Invalid photo format.');
        }
        if ($photo !== '' && strlen($photo) > 2_000_000) {
            fail('Photo is too large — please use a smaller image (under ~1.5MB).');
        }
        $sql     .= ", photo = ?";
        $params[] = $photo !== '' ? $photo : null;
    }

    $sql .= " WHERE id = ?";
    $params[] = $id;
    db_run($sql, $params);

    // Keep the topbar in sync immediately — no re-login required. Photo
    // itself is deliberately not cached in session (see current_user_photo()
    // in includes/auth.php); it's re-read from the DB on next page load.
    $_SESSION['user_name'] = $name;
    $_SESSION['user_av']   = $avatar ?: strtoupper(substr($name, 0, 2));

    log_action('update', 'users', $id, "Updated own profile (\"{$name}\", @{$username})");

    ok(['msg' => 'Profile updated successfully.']);
}

// ── Change own password ───────────────────────────────────────────
function api_change_password(array $b): void {
    $id  = current_user_id();
    $cur = (string) ($b['current_password'] ?? '');
    $new = (string) ($b['new_password']     ?? '');

    if (!$cur) fail('Enter your current password.');
    if (strlen($new) < 6) fail('New password must be at least 6 characters.');

    $user = db_row("SELECT password FROM users WHERE id = ?", [$id]);
    if (!$user || !password_verify($cur, $user['password'])) {
        fail('Current password is incorrect.');
    }
    if (password_verify($new, $user['password'])) {
        fail('New password must be different from your current password.');
    }

    $hash = password_hash($new, PASSWORD_DEFAULT);
    db_run("UPDATE users SET password = ? WHERE id = ?", [$hash, $id]);

    log_action('update', 'users', $id, 'Changed own password');

    ok(['msg' => 'Password changed successfully.']);
}

function ok(array $extra = []): void {
    echo json_encode(array_merge(['success' => true], $extra));
    exit;
}
function fail(string $msg): never {
    echo json_encode(['success' => false, 'error' => $msg]);
    exit;
}
