<?php
// =============================================================
//  POST /api/v1/staff/create
//
//  Creates a staff account — wraps app/add_user.php's staff-only path
//  (Rotation_Nurse/Clinical_Student creation is out of scope here, same
//  as app/manage_staffs.php's own scope). Same default password
//  ('STH@12345'), same password_change_required=1, same role_id lookup
//  by usertype, same global email/phone uniqueness check across all
//  three account tables via the shared checkGlobalDuplicate() helper.
// =============================================================

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('create_user');

const DEFAULT_STAFF_PASSWORD = 'STH@12345';
$staffTypes = ['Admin', 'Chief_Preceptor', 'Preceptor', 'Nurse_Manager', 'In_Charge'];

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

$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'] ?? '');
$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');

if ($usertype === 'Admin' && !PermissionManager::sessionCan('assign_role')) {
    Api::error(403, 'Forbidden', 'You do not have permission to create Admin users');
}

// Global uniqueness across users/rotation_nurses/clinical_students — same
// helper the web form uses, so the rule can't drift between the two.
if ($dup = checkGlobalDuplicate($conn, 'email', $email, null, 0, ['rotation_nurses', 'clinical_students'])) {
    Api::error(409, 'DuplicateEmail', "This email is already used by another account ({$dup['name']}).");
}
if ($phone !== '' && ($dup = checkGlobalDuplicate($conn, 'phone', $phone, null, 0, ['rotation_nurses', 'clinical_students']))) {
    Api::error(409, 'DuplicatePhone', "This phone number is already used by another account ({$dup['name']}).");
}

$existsStmt = $conn->prepare('SELECT id FROM users WHERE email = ? OR username = ?');
$existsStmt->bind_param('ss', $email, $username);
$existsStmt->execute();
$existsStmt->store_result();
if ($existsStmt->num_rows > 0) {
    $existsStmt->close();
    Api::error(409, 'DuplicateUser', 'Email or username already exists');
}
$existsStmt->close();

$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;
$designationOrNull = $designation !== '' ? $designation : null;
$passwordHash = password_hash(DEFAULT_STAFF_PASSWORD, PASSWORD_BCRYPT);
$createdBy = $account->getFirstname() . ' ' . $account->getSurname();

$cols = ['firstname', 'surname', 'email', 'phone', 'gender', 'password', 'profile',
    'usertype', 'username', 'grade', 'designation', 'role_id', 'password_change_required', 'status', 'created_by'];
$vals = [$firstname, $surname, $email, $phoneOrNull, $genderOrNull, $passwordHash, 'default.png',
    $usertype, $username, $grade, $designationOrNull, $roleId, 1, 'Active', $createdBy];
$types = 'sssssss' . 'ssssi' . 'iss'; // firstname..profile(7 s) + usertype..role_id(4s+1i) + pcr(i)+status(s)+created_by(s)

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

$ph = implode(',', array_fill(0, count($vals), '?'));
$stmt = $conn->prepare('INSERT INTO users (' . implode(',', $cols) . ") VALUES ($ph)");
$stmt->bind_param($types, ...$vals);

if (!$stmt->execute()) {
    Api::error(500, 'ServerError', 'Could not create the account. Please try again.');
}
$newId = $conn->insert_id;
$stmt->close();

$permManager = new PermissionManager($conn);
$permManager->logAudit($account->getId(), 'create_user', 'user', $newId, null, json_encode(['usertype' => $usertype]));

Api::success(['id' => $newId, 'default_password' => DEFAULT_STAFF_PASSWORD]);
