<?php
// =============================================================
//  GET  /api/v1/attendance/checkin_scan?unit_id=NN&token=XXXXXXXX
//  POST /api/v1/attendance/checkin_scan   { "unit_id": NN, "token": "XXXXXXXX" }
//
//  Mobile equivalent of checkin.php — the Flutter app's camera scans the
//  same rotating QR code shown on a unit's display screen
//  (app/checkin_display.php) instead of a phone browser following a link.
//  Same rotating-token verification (include/CheckinToken.php), same
//  eligibility/duplicate/insert logic (include/CheckinHelpers.php, shared
//  with checkin.php so there's one implementation of "who's allowed to
//  check in where").
//
//  GET is read-only (eligibility + already-checked-in-today, for the app
//  to render a confirmation card) — POST is the only path that writes,
//  and re-verifies both the token and eligibility itself rather than
//  trusting a prior GET, same "a mere request must never silently mark
//  someone present" rule checkin.php's own header comment states.
// =============================================================

require_once __DIR__ . '/../_bootstrap.php';
require_once __DIR__ . '/../../../include/rate_limiter.php';
require_once __DIR__ . '/../../../include/CheckinToken.php';
require_once __DIR__ . '/../../../include/CheckinHelpers.php';

$account = api_authenticate();
$userTable = $account->getTable();
$userId    = $account->getId();

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $unitId = (int)($_GET['unit_id'] ?? 0);
    $token  = trim((string)($_GET['token'] ?? ''));
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $body   = Api::body();
    $unitId = (int)($body['unit_id'] ?? 0);
    $token  = trim((string)($body['token'] ?? ''));
} else {
    Api::error(405, 'MethodNotAllowed', 'Use GET or POST');
}

if (!$unitId || $token === '') {
    Api::error(422, 'ValidationError', 'unit_id and token are required');
}
if (!in_array($userTable, ['rotation_nurses', 'clinical_students'], true)) {
    Api::error(403, 'Forbidden', 'Self check-in is for rotation nurses and clinical students only');
}
if (!CheckinToken::verify($unitId, $token)) {
    Api::error(410, 'ExpiredCode', 'This QR code has expired. Please scan the current code on the display screen.');
}

$rl = rateLimitAttempt('api_checkin:' . $userId . ':' . $unitId, 10, 300);
if ($rl['blocked']) {
    Api::error(429, 'TooManyAttempts', 'Too many attempts. Please wait a few minutes and try again.', [
        'retry_after' => $rl['retry_after'],
    ]);
}

$check = checkSelfCheckinEligibility($conn, $userTable, $userId, $unitId);

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    Api::success($check);
}

// POST: only writes if eligible and not already checked in.
if (!$check['eligible']) {
    Api::error(403, 'NotEligible', $check['message']);
}
if ($check['already']) {
    Api::success(['status' => 'already_checked_in', 'message' => $check['message'], 'unit_name' => $check['unit_name']]);
}

$result = recordSelfCheckin($conn, $userTable, $userId, $unitId, $check['unit_name'], $check['context']);
if (!$result['ok']) {
    Api::error(500, 'CheckinFailed', $result['message']);
}

Api::success(['status' => 'checked_in', 'message' => $result['message'], 'unit_name' => $check['unit_name']]);
