<?php
// =============================================================
//  POST /api/v1/attendance/student_mark
//
//  Staff-facing roll-call submission for Clinical Students — mirrors
//  app/clinical_attendance.php's POST handler. Requires 'assess_students'.
//
//  Body: {
//    "attendance_date": "2026-08-16",
//    "unit_id": 5, "unit_name": "THEATRE", "rotation_id": 12,
//    "records": [ { "student_id": 9, "status": "Present", "remarks": null }, ... ]
//  }
//
//  Unlike nurse_mark.php, the web page this mirrors blocks the WHOLE
//  submission up front if ANY staff-marked (non-self-checkin) row already
//  exists for this unit/rotation/date, rather than skipping individual
//  already-marked students — replicated here for the same reason: it's a
//  race-condition guard against two staff members batch-marking the same
//  unit concurrently, and the pending list already excludes anyone marked
//  before the page/screen was loaded.
// =============================================================

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

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

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

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

$att_date    = trim((string)($body['attendance_date'] ?? ''));
$unit_id     = (int)($body['unit_id'] ?? 0);
$unit_name   = trim((string)($body['unit_name'] ?? ''));
$rotation_id = (int)($body['rotation_id'] ?? 0);
$records     = is_array($body['records'] ?? null) ? $body['records'] : [];

if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $att_date) || !$unit_id || !$rotation_id || !$unit_name || empty($records)) {
    Api::error(422, 'ValidationError', 'attendance_date, unit_id, unit_name, rotation_id, and at least one record are required');
}

const STATUSES = ['Present', 'Absent', 'Late', 'Excused'];

// Block saving if staff-marked (non-self-checkin) attendance already exists
// for this unit/rotation/date — same upfront check as the web page.
$has_self_checkin_col = $conn->query("SHOW COLUMNS FROM clinical_attendance LIKE 'is_self_checkin'")->num_rows > 0;
$block_sql = 'SELECT COUNT(*) AS n FROM clinical_attendance WHERE attendance_date = ? AND unit_id = ? AND clinical_rotation_id = ?'
    . ($has_self_checkin_col ? ' AND is_self_checkin = 0' : '');
$block = $conn->prepare($block_sql);
$block->bind_param('sii', $att_date, $unit_id, $rotation_id);
$block->execute();
$alreadyTaken = (int)$block->get_result()->fetch_assoc()['n'];
$block->close();

if ($alreadyTaken > 0) {
    Api::error(409, 'AlreadyMarked', "Attendance has already been taken for {$unit_name} on {$att_date}.");
}

$saved     = 0;
$skipped   = [];
$accountId = $account->getId();

foreach ($records as $r) {
    $student_id = (int)($r['student_id'] ?? 0);
    $status     = (string)($r['status'] ?? '');
    $remark     = isset($r['remarks']) && trim((string)$r['remarks']) !== '' ? trim((string)$r['remarks']) : null;

    if (!$student_id || !in_array($status, STATUSES, true)) {
        $skipped[] = $r;
        continue;
    }

    $ins = $conn->prepare('
        INSERT INTO clinical_attendance
            (clinical_student_id, clinical_rotation_id, unit_id, unit_name, attendance_date, status, remarks, marked_by)
        VALUES (?,?,?,?,?,?,?,?)
    ');
    $ins->bind_param(
        'iiissssi',
        $student_id, $rotation_id, $unit_id, $unit_name, $att_date, $status, $remark, $accountId
    );
    if ($ins->execute()) {
        $saved++;
    } else {
        $skipped[] = $r + ['reason' => 'db_error'];
    }
    $ins->close();
}

Api::success([
    'saved'   => $saved,
    'skipped' => $skipped,
]);
