<?php
/**
 * POST /api/v1/drafts.php
 *
 * Token-authenticated parity of grade_autosave.php: upsert an in-progress
 * grading draft so the live dashboard reflects "in progress" and the work
 * survives a crash. The mobile app calls this while online; offline work is
 * held locally and submitted via attempts.php.
 *
 * Body: { candidate_id, form_id, payload: { score, item_comment, global_comment } }
 */

require_once __DIR__ . '/../../config.php';
require_once __DIR__ . '/../../lib/api.php';

api_require_method('POST');
$user = api_auth($pdo);

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

if ($candidateId <= 0 || $formId <= 0 || $payload === null) {
    api_error('invalid_input', 422);
}

// Facility scoping: examiners may only draft candidates in their facility.
if (!perms_is_super($user) && !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']) {
        api_error('forbidden', 403);
    }
}

// Sanitise/cap the payload (identical rules to grade_autosave.php).
$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) {
    api_error('payload_too_large', 413);
}

try {
    $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
    ')->execute([$user['id'], $candidateId, $formId, $json]);

    // Same side effect as the web autosave: mark the session in_progress.
    try {
        $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'
        ")->execute([$candidateId, $user['id']]);
    } catch (Throwable $e) {
        error_log('api drafts -> in_progress: ' . $e->getMessage());
    }

    api_ok(['ts' => date('c')]);
} catch (Throwable $e) {
    error_log('api drafts: ' . $e->getMessage());
    api_error('save_failed', 500);
}
