<?php
// =============================================================
//  POST /api/v1/admin_students/create
//
//  Onboards a Clinical Student account — wraps app/add_clinical_
//  student.php's validation and insert logic. No profile-photo upload
//  from mobile (out of scope, same simplification as api/v1/staff/
//  create.php) and no SMS/email side effects — the default password is
//  returned in the response instead, for the admin to relay directly,
//  matching how api/v1/staff/create.php and the password-reset flow
//  already work on mobile.
// =============================================================

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_STUDENT_PASSWORD = 'STHstudent123';
$clinicalLevels = [
    'Year 1', 'Year 2', 'Year 3', 'Year 4',
    'HND 1', 'HND 2',
    'Degree 1', 'Degree 2', 'Degree 3', 'Degree 4',
    'Postgraduate',
];

$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'] ?? '');
$studentId   = trim((string)($body['student_id'] ?? ''));
$schoolName  = trim((string)($body['school_name'] ?? ''));
$level       = trim((string)($body['level'] ?? ''));
$programme   = trim((string)($body['programme'] ?? ''));
$supervisor  = trim((string)($body['supervisor'] ?? ''));

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 ($studentId === '') Api::error(422, 'ValidationError', 'Student ID is required');
if ($schoolName === '') Api::error(422, 'ValidationError', 'School / Institution name is required');
if (!in_array($level, $clinicalLevels, true)) Api::error(422, 'ValidationError', 'A valid Level / Year is required');
if ($phone !== '' && !preg_match('/^[0-9]{10,15}$/', $phone)) Api::error(422, 'ValidationError', 'Phone must be 10-15 digits');

// Global uniqueness — email/phone must not already belong to a staff or
// rotation-nurse account.
$otherTables = ['users', 'rotation_nurses'];
if ($dup = checkGlobalDuplicate($conn, 'email', $email, null, 0, $otherTables)) {
    Api::error(409, 'DuplicateEmail', "This email is already used by another account ({$dup['name']}).");
}
if ($phone !== '' && ($dup = checkGlobalDuplicate($conn, 'phone', $phone, null, 0, $otherTables))) {
    Api::error(409, 'DuplicatePhone', "This phone number is already used by another account ({$dup['name']}).");
}

// Duplicate check within clinical_students — also surfaces who the
// existing match is, since this is the expected outcome for a RETURNING
// student rather than an error to "fix".
$chk = $conn->prepare('SELECT id, firstname, surname, rotation_status FROM clinical_students WHERE email = ? OR student_id = ?');
$chk->bind_param('ss', $email, $studentId);
$chk->execute();
$existing = $chk->get_result()->fetch_assoc();
$chk->close();
if ($existing) {
    $existingName = trim($existing['firstname'] . ' ' . $existing['surname']);
    $existingStatus = str_replace('_', ' ', $existing['rotation_status']);
    Api::error(409, 'AlreadyRegistered',
        "A student with this email or Student ID is already registered: {$existingName} "
        . "(current rotation status: {$existingStatus}). If they are returning for another "
        . "rotation, assign them a new rotation instead of registering them again — their "
        . "profile and history are kept automatically.",
        ['existing_student_id' => (int)$existing['id']]
    );
}

$phoneOrNull      = $phone !== '' ? $phone : null;
$genderOrNull     = $gender !== '' ? $gender : null;
$programmeOrNull  = $programme !== '' ? $programme : null;
$supervisorOrNull = $supervisor !== '' ? $supervisor : null;
$passwordHash     = password_hash(DEFAULT_STUDENT_PASSWORD, PASSWORD_BCRYPT);
$createdById      = $account->getId();

$cols = ['firstname', 'surname', 'email', 'phone', 'gender', 'password', 'profile',
    'password_change_required', 'student_id', 'school_name', 'level', 'programme',
    'supervisor_name', 'rotation_status', 'status', 'created_by'];
$vals = [$firstname, $surname, $email, $phoneOrNull, $genderOrNull, $passwordHash, 'default.png',
    1, $studentId, $schoolName, $level, $programmeOrNull, $supervisorOrNull, 'Not_started', 'Active', $createdById];
$types = 'sssssss' . 'i' . 'sssssss' . 'i'; // firstname..profile(7s) + pcr(i) + student_id..status(7s) + created_by(i)

if (strlen($types) !== count($vals)) {
    error_log('admin_students/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 clinical_students (' . 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', 'clinical_student', $newId, null,
    json_encode(['email' => $email, 'student_id' => $studentId, 'level' => $level, 'rotation_status' => 'Not_started'])
);

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