<?php
// =============================================================
//  POST /api/v1/staff/update
//
//  Edits a staff account — wraps app/edit_user.php's staff (users table)
//  branch. No profile-photo upload from mobile (out of scope; keeps this
//  simple JSON in/JSON out rather than multipart). Same self-edit
//  safeguard as the web page: if you're editing your own account, the
//  usertype/status you sent are silently ignored and replaced with your
//  real current values — you cannot self-promote or self-deactivate
//  through this endpoint, only through the dedicated toggle_status
//  endpoint's own self-guard (which blocks it outright).
// =============================================================

require_once __DIR__ . '/../_bootstrap.php';
require_once __DIR__ . '/../../../include/account_helpers.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    Api::error(405, 'MethodNotAllowed', 'Use POST');
}

$account = api_authenticate();
api_require_permission('edit_user');

$staffTypes = ['Admin', 'Chief_Preceptor', 'Preceptor', 'Nurse_Manager', 'In_Charge'];
$body = json_decode(file_get_contents('php://input'), true) ?? [];

$editId = (int)($body['id'] ?? 0);
if (!$editId) Api::error(422, 'ValidationError', 'id is required');

$existing = $conn->prepare("SELECT usertype, status FROM users WHERE id = ?");
$existing->bind_param('i', $editId);
$existing->execute();
$existingRow = $existing->get_result()->fetch_assoc();
$existing->close();
if (!$existingRow) {
    Api::error(404, 'NotFound', 'Staff account not found');
}

$firstname   = trim((string)($body['firstname'] ?? ''));
$surname     = trim((string)($body['surname'] ?? ''));
$email       = filter_var(trim((string)($body['email'] ?? '')), FILTER_SANITIZE_EMAIL);
$phone       = trim((string)($body['phone'] ?? ''));
$gender      = (string)($body['gender'] ?? '');
$usertype    = (string)($body['usertype'] ?? '');
$status      = in_array($body['status'] ?? '', ['Active', 'Inactive'], true) ? $body['status'] : 'Active';
$username    = trim((string)($body['username'] ?? ''));
$grade       = trim((string)($body['grade'] ?? ''));
$designation = trim((string)($body['designation'] ?? ''));

if ($firstname === '') Api::error(422, 'ValidationError', 'First name is required');
if ($surname === '') Api::error(422, 'ValidationError', 'Last name is required');
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) Api::error(422, 'ValidationError', 'A valid email is required');
if (!in_array($usertype, $staffTypes, true)) Api::error(422, 'ValidationError', 'Invalid usertype');
if ($phone !== '' && !preg_match('/^[0-9]{10,15}$/', $phone)) Api::error(422, 'ValidationError', 'Phone must be 10-15 digits');
if ($username === '') Api::error(422, 'ValidationError', 'Username is required');

// Same self-edit safeguard as edit_user.php: editing your own account
// can never change your own usertype or status through this endpoint.
$isSelf = ($editId === $account->getId());
if ($isSelf) {
    $usertype = $existingRow['usertype'];
    $status   = $existingRow['status'];
}

if ($usertype === 'Admin' && !PermissionManager::sessionCan('assign_role')) {
    Api::error(403, 'Forbidden', 'You do not have permission to assign the Admin role');
}
if (checkTableDuplicate($conn, 'users', 'username', $username, $editId)) {
    Api::error(409, 'DuplicateUsername', 'Username already exists');
}
if ($dup = checkGlobalDuplicate($conn, 'email', $email, 'users', $editId, ['users', 'rotation_nurses', 'clinical_students'])) {
    if ($dup['id'] !== $editId || $dup['table'] !== 'users') {
        Api::error(409, 'DuplicateEmail', "This email is already used by another account ({$dup['name']}).");
    }
}

$roleStmt = $conn->prepare('SELECT id FROM roles WHERE name = ?');
$roleStmt->bind_param('s', $usertype);
$roleStmt->execute();
$roleRow = $roleStmt->get_result()->fetch_assoc();
$roleStmt->close();
if (!$roleRow) {
    Api::error(500, 'ServerError', "No matching role found for usertype '$usertype'");
}
$roleId = (int)$roleRow['id'];

$phoneOrNull = $phone !== '' ? $phone : null;
$genderOrNull = $gender !== '' ? $gender : null;
$gradeOrNull = $grade !== '' ? $grade : null;
$designationOrNull = $designation !== '' ? $designation : null;

$stmt = $conn->prepare("
    UPDATE users SET firstname=?, surname=?, email=?, phone=?, gender=?,
        usertype=?, status=?, username=?, grade=?, designation=?, role_id=?
    WHERE id=?
");
$types = 'ssssssssssii'; // 10 strings (firstname..designation) + role_id(i) + id(i) — verified: 10 s + 2 i = 12 chars
$vals = [$firstname, $surname, $email, $phoneOrNull, $genderOrNull, $usertype, $status, $username, $gradeOrNull, $designationOrNull, $roleId, $editId];

if (strlen($types) !== count($vals)) {
    error_log('staff/update.php: type string length (' . strlen($types) . ') != value count (' . count($vals) . ')');
    Api::error(500, 'ServerError', 'Internal error preparing the account record.');
}

$stmt->bind_param($types, ...$vals);
if (!$stmt->execute()) {
    Api::error(500, 'ServerError', 'Could not update the account. Please try again.');
}
$stmt->close();

$permManager = new PermissionManager($conn);
$permManager->logAudit($account->getId(), 'edit_user', 'user', $editId, json_encode($existingRow), json_encode(['usertype' => $usertype, 'status' => $status]));

Api::success(['id' => $editId]);
