<?php
// grade_autosave.php – stores in-progress grading drafts. JSON in / JSON out.
require_once __DIR__ . '/auth.php';
require_login();

header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'method_not_allowed']);
    exit;
}

if (!csrf_check()) {
    http_response_code(403);
    echo json_encode(['ok' => false, 'error' => 'csrf']);
    exit;
}

$raw  = file_get_contents('php://input');
$body = json_decode($raw ?: '[]', true);
if (!is_array($body)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'bad_json']);
    exit;
}

$user        = current_user();
$candidateId = v_int($body['candidate_id'] ?? 0, 1);
$formId      = v_int($body['form_id']      ?? 0, 1);
$payload     = is_array($body['payload'] ?? null) ? $body['payload'] : null;

if ($candidateId <= 0 || $formId <= 0 || $payload === null) {
    http_response_code(422);
    echo json_encode(['ok' => false, 'error' => 'invalid_input']);
    exit;
}

// Permission: facility users can only autosave candidates within their facility
if (!is_super_admin() && !empty($user['facility_id'])) {
    $check = $pdo->prepare('SELECT facility_id FROM candidates WHERE id = ? AND deleted_at IS NULL');
    $check->execute([$candidateId]);
    $row = $check->fetch();
    if (!$row || (int)$row['facility_id'] !== (int)$user['facility_id']) {
        http_response_code(403);
        echo json_encode(['ok' => false, 'error' => 'forbidden']);
        exit;
    }
}

// Sanitise the payload – cap sizes
$clean = [
    'score'         => [],
    'item_comment'  => [],
    'global_comment' => '',
];
if (isset($payload['score']) && is_array($payload['score'])) {
    foreach ($payload['score'] as $k => $v) {
        if (!preg_match('/^\d+$/', (string)$k)) continue;
        $clean['score'][(string)(int)$k] = (string) v_int($v, 0, 1000, 0);
    }
}
if (isset($payload['item_comment']) && is_array($payload['item_comment'])) {
    foreach ($payload['item_comment'] as $k => $v) {
        if (!preg_match('/^\d+$/', (string)$k)) continue;
        $clean['item_comment'][(string)(int)$k] = v_clean_string((string)$v, 1000);
    }
}
$clean['global_comment'] = v_clean_string((string)($payload['global_comment'] ?? ''), 2000);

$json = json_encode($clean, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if ($json === false || strlen($json) > 60000) {
    http_response_code(413);
    echo json_encode(['ok' => false, 'error' => 'payload_too_large']);
    exit;
}

try {
    // upsert (unique key examiner+candidate+form)
    $stmt = $pdo->prepare("
        INSERT INTO grade_drafts (examiner_id, candidate_id, form_id, payload)
        VALUES (?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE payload = VALUES(payload), updated_at = CURRENT_TIMESTAMP
    ");
    $stmt->execute([$user['id'], $candidateId, $formId, $json]);

    // First-save side effect: flip the session to in_progress so the dashboard
    // can show the moment grading actually started.
    try {
        $upd = $pdo->prepare("
            UPDATE osce_sessions
            SET status = 'in_progress',
                grading_started_at = COALESCE(grading_started_at, NOW()),
                last_action = 'Grading in progress'
            WHERE candidate_id = ?
              AND examiner_id  = ?
              AND status = 'checked_in'
        ");
        $upd->execute([$candidateId, $user['id']]);
    } catch (Throwable $e) {
        error_log('autosave -> in_progress: ' . $e->getMessage());
    }

    echo json_encode(['ok' => true, 'ts' => date('c')]);
} catch (Throwable $e) {
    error_log('grade_autosave: ' . $e->getMessage());
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'save_failed']);
}
