<?php
require_once '../../config/database.php';
require_once '../../config/auth.php';
require_once '../../config/rbac.php';
require_once '../../includes/ExamGradingService.php';

header('Content-Type: application/json');

if (!isLoggedIn()) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Authentication required']);
    exit;
}

$db = getDB();
$userId = (int) $_SESSION['user_id'];
$role = $_SESSION['role'] ?? 'student';
$method = $_SERVER['REQUEST_METHOD'];

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

$data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Invalid JSON data']);
    exit;
}

$action = $data['action'] ?? '';

try {
    switch ($action) {
        case 'list_submissions':
            $examId = isset($data['exam_id']) ? (int) $data['exam_id'] : null;
            $status = $data['status'] ?? 'pending';
            echo json_encode([
                'success' => true,
                'submissions' => ExamGradingService::getGradingQueue($db, $userId, $role, $examId, $status)
            ]);
            break;

        case 'get_submission':
            if (empty($data['attempt_id'])) {
                throw new Exception('Attempt ID is required');
            }
            $submission = ExamGradingService::getSubmission($db, (int) $data['attempt_id'], $userId, $role);
            echo json_encode([
                'success' => true,
                'submission' => $submission['attempt'],
                'student' => $submission['student'],
                'questions' => $submission['questions']
            ]);
            break;

        case 'save_grades':
            handleSaveGrades($db, $userId, $role, $data);
            break;

        case 'bulk_grade':
            handleBulkGrade($db, $userId, $role, $data);
            break;

        case 'save_feedback':
            handleSaveFeedback($db, $userId, $role, $data);
            break;

        case 'get_grading_stats':
            echo json_encode([
                'success' => true,
                'stats' => ExamGradingService::getGradingStats($db, $userId, $role)
            ]);
            break;

        default:
            throw new Exception('Invalid action');
    }
} catch (Throwable $e) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}

function handleSaveGrades(PDO $db, int $userId, string $role, array $data): void
{
    if (empty($data['attempt_id'])) {
        throw new Exception('Attempt ID is required');
    }

    $attemptId = (int) $data['attempt_id'];
    $attempt = ExamGradingService::getAttempt($db, $attemptId);
    if (!$attempt) {
        throw new Exception('Attempt not found');
    }

    $stmt = $db->prepare('SELECT instructor_id FROM exams WHERE id = ?');
    $stmt->execute([$attempt['exam_id']]);
    $instructorId = (int) $stmt->fetchColumn();

    if ($role !== 'admin' && !($role === 'instructor' && $instructorId === $userId)) {
        throw new Exception('Access denied');
    }

    $result = ExamGradingService::saveManualGrades(
        $db,
        $attemptId,
        $data['question_scores'] ?? [],
        $data['question_feedback'] ?? [],
        $userId,
        $data['feedback'] ?? ''
    );

    echo json_encode([
        'success' => true,
        'message' => 'Grades saved successfully',
        'data' => $result
    ]);
}

function handleBulkGrade(PDO $db, int $userId, string $role, array $data): void
{
    $attemptIds = $data['attempt_ids'] ?? [];
    if (empty($attemptIds)) {
        throw new Exception('No attempts selected');
    }

    $updated = 0;
    foreach ($attemptIds as $attemptId) {
        $attempt = ExamGradingService::getAttempt($db, (int) $attemptId);
        if (!$attempt) {
            continue;
        }

        $stmt = $db->prepare('SELECT instructor_id FROM exams WHERE id = ?');
        $stmt->execute([$attempt['exam_id']]);
        $instructorId = (int) $stmt->fetchColumn();

        if ($role !== 'admin' && !($role === 'instructor' && $instructorId === $userId)) {
            continue;
        }

        ExamGradingService::saveManualGrades(
            $db,
            (int) $attemptId,
            $data['question_scores'] ?? [],
            $data['question_feedback'] ?? [],
            $userId,
            $data['feedback'] ?? ''
        );
        $updated++;
    }

    echo json_encode([
        'success' => true,
        'message' => "Bulk graded $updated submissions",
        'updated_count' => $updated
    ]);
}

function handleSaveFeedback(PDO $db, int $userId, string $role, array $data): void
{
    if (empty($data['attempt_id'])) {
        throw new Exception('Attempt ID is required');
    }

    $attempt = ExamGradingService::getAttempt($db, (int) $data['attempt_id']);
    if (!$attempt) {
        throw new Exception('Attempt not found');
    }

    $stmt = $db->prepare('SELECT instructor_id FROM exams WHERE id = ?');
    $stmt->execute([$attempt['exam_id']]);
    $instructorId = (int) $stmt->fetchColumn();

    if ($role !== 'admin' && !($role === 'instructor' && $instructorId === $userId)) {
        throw new Exception('Access denied');
    }

    $stmt = $db->prepare("
        UPDATE exam_attempts
        SET feedback = ?, graded_by = ?, graded_at = NOW(), updated_at = NOW()
        WHERE id = ?
    ");
    $stmt->execute([$data['feedback'] ?? '', $userId, $attempt['id']]);

    echo json_encode(['success' => true, 'message' => 'Feedback saved']);
}
