<?php
/**
 * Offline confirmation sync endpoint.
 * POST JSON: {"confirmations": [{token, session_id, scanned_at, device_info}]}
 * Auth: canteen_staff_authenticated OR valid EduTrack role
 * Idempotent — duplicates are logged but not errored.
 */
if (session_status() === PHP_SESSION_NONE) session_start();
header('Content-Type: application/json');

require_once '../config.php';
require_once '../includes/canteen_helpers.php';

canteen_require_active();

$is_pin_session  = !empty($_SESSION['canteen_staff_authenticated']);
$is_role_session = !empty($_SESSION['user_id']);
if (!$is_pin_session && !$is_role_session) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Not authenticated.']);
    exit;
}

// Accept JSON body
$raw   = file_get_contents('php://input');
$body  = json_decode($raw, true);
$items = is_array($body['confirmations'] ?? null) ? $body['confirmations'] : [];

if (empty($items)) {
    echo json_encode(['success' => true, 'processed' => 0, 'results' => []]);
    exit;
}

// Sanitise: max 500 items per sync
$items = array_slice($items, 0, 500);

$conn     = getDBConnection();
$actor_id = $is_role_session ? (int)$_SESSION['user_id'] : 0;
$results  = [];

foreach ($items as $item) {
    $token      = trim((string)($item['token']      ?? ''));
    $session_id = (int)($item['session_id'] ?? 0);
    $scanned_at = trim((string)($item['scanned_at'] ?? ''));
    $device_info= substr(trim((string)($item['device_info'] ?? '')), 0, 255);

    if ($token === '' || $session_id <= 0) {
        $results[] = ['token' => substr($token, 0, 10) . '…', 'result' => 'skip_invalid'];
        continue;
    }

    // Normalise scanned_at timestamp
    $scan_ts = $scanned_at ? date('Y-m-d H:i:s', (int)$scanned_at) : date('Y-m-d H:i:s');

    // Re-validate HMAC (security gate — this is the real check)
    $student_id = canteen_validate_session_token($token, $session_id);
    if ($student_id === false) {
        $results[] = ['token' => substr($token, 0, 10) . '…', 'result' => 'invalid_token'];

        // Log the bad token attempt
        $ins = $conn->prepare(
            "INSERT INTO canteen_scans (session_id, student_id, scan_result, verification_method, scanned_by, scanned_at, device_info)
             VALUES (?, 0, 'invalid_token', 'qr', ?, ?, ?)"
        );
        $ins->bind_param('iiss', $session_id, $actor_id, $scan_ts, $device_info);
        $ins->execute();
        $ins->close();
        continue;
    }

    // Check if already synced (idempotency — same token + session + approximate time window)
    $dup = $conn->prepare(
        "SELECT id FROM canteen_scans
         WHERE session_id = ? AND student_id = ? AND scan_result = 'success'
         LIMIT 1"
    );
    $dup->bind_param('ii', $session_id, $student_id);
    $dup->execute();
    $already = $dup->get_result()->fetch_assoc();
    $dup->close();

    if ($already) {
        $results[] = ['token' => substr($token, 0, 10) . '…', 'result' => 'already_synced'];
        continue;
    }

    // Find entitlement
    $entStmt = $conn->prepare(
        "SELECT id, status FROM canteen_entitlements WHERE qr_token = ? AND session_id = ? LIMIT 1"
    );
    $entStmt->bind_param('si', $token, $session_id);
    $entStmt->execute();
    $ent = $entStmt->get_result()->fetch_assoc();
    $entStmt->close();

    $conn->begin_transaction();
    try {
        $entitlement_id = 0;

        if ($ent) {
            $entitlement_id = (int)$ent['id'];
            if ($ent['status'] === 'pending') {
                $upd = $conn->prepare(
                    "UPDATE canteen_entitlements
                     SET status = 'confirmed', confirmed_at = ?, verification_method = 'qr',
                         confirmed_by = ?, offline_queued = 1, offline_synced_at = NOW()
                     WHERE id = ?"
                );
                $upd->bind_param('sii', $scan_ts, $actor_id, $entitlement_id);
                $upd->execute();
                $upd->close();
            }
        }

        // Insert scan record
        $insStmt = $conn->prepare(
            "INSERT INTO canteen_scans
             (session_id, student_id, entitlement_id, scan_result, verification_method,
              scanned_by, scanned_at, device_info)
             VALUES (?, ?, ?, 'success', 'qr', ?, ?, ?)"
        );
        $insStmt->bind_param('iiiiss', $session_id, $student_id, $entitlement_id,
                                       $actor_id, $scan_ts, $device_info);
        $insStmt->execute();
        $insStmt->close();

        $conn->commit();
        $results[] = ['token' => substr($token, 0, 10) . '…', 'result' => 'synced'];

    } catch (Exception $e) {
        $conn->rollback();
        $results[] = ['token' => substr($token, 0, 10) . '…', 'result' => 'error'];
    }
}

$synced_count = count(array_filter($results, fn($r) => $r['result'] === 'synced'));
if ($synced_count > 0) {
    logActivity($conn, $actor_id, 'canteen_offline_sync',
        "Synced {$synced_count} offline confirmation(s)");
}

$conn->close();

echo json_encode([
    'success'   => true,
    'processed' => count($results),
    'synced'    => $synced_count,
    'results'   => $results,
]);
