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

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

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

// Check if user is instructor or admin
if (!hasAnyRole(['instructor', 'admin'])) {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Access denied']);
    exit;
}

$db = getDB();
$userId = $_SESSION['user_id'];
$attemptId = intval($_GET['attempt_id'] ?? 0);

if (!$attemptId) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Attempt ID is required']);
    exit;
}

try {
    // Get submission details
    $stmt = $db->prepare("
        SELECT
            ea.*,
            e.title as exam_title,
            e.instructor_id,
            e.passing_score,
            u.username as student_name,
            u.email,
            up.first_name,
            up.last_name
        FROM exam_attempts ea
        JOIN exams e ON ea.exam_id = e.id
        JOIN users u ON ea.student_id = u.id
        LEFT JOIN user_profiles up ON u.id = up.user_id
        WHERE ea.id = ?
    ");
    $stmt->execute([$attemptId]);
    $submission = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$submission) {
        throw new Exception('Submission not found');
    }

    // Verify access
    if ($submission['instructor_id'] !== $userId && !hasAnyRole(['admin'])) {
        throw new Exception('Access denied');
    }

    // Get exam questions with student answers
    $stmt = $db->prepare("
        SELECT 
            q.id as question_id,
            q.content,
            q.question_type,
            q.points as default_points,
            eq.points,
            eq.sort_order,
            qo.id as option_id,
            qo.option_text,
            qo.is_correct
        FROM exam_questions eq
        JOIN questions q ON eq.question_id = q.id
        LEFT JOIN question_options qo ON q.id = qo.question_id
        WHERE eq.exam_id = ?
        ORDER BY eq.sort_order, qo.sort_order
    ");
    $stmt->execute([$submission['exam_id']]);
    $questionData = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Group questions and options
    $questions = [];
    foreach ($questionData as $row) {
        $qid = $row['question_id'];
        if (!isset($questions[$qid])) {
            $questions[$qid] = [
                'question_id' => $qid,
                'content' => $row['content'],
                'question_type' => $row['question_type'],
                'points' => $row['points'],
                'sort_order' => $row['sort_order'],
                'options' => [],
                'earned_points' => 0,
                'feedback' => ''
            ];
        }
        if ($row['option_id']) {
            $questions[$qid]['options'][] = [
                'id' => $row['option_id'],
                'option_text' => $row['option_text'],
                'is_correct' => $row['is_correct']
            ];
        }
    }

    // Get any existing question-level grades/feedback
    $stmt = $db->prepare("
        SELECT question_id, points_earned, feedback
        FROM exam_question_grades
        WHERE attempt_id = ?
    ");
    $stmt->execute([$attemptId]);
    $grades = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach ($grades as $grade) {
        if (isset($questions[$grade['question_id']])) {
            $questions[$grade['question_id']]['earned_points'] = $grade['points_earned'];
            $questions[$grade['question_id']]['feedback'] = $grade['feedback'];
        }
    }

    // Calculate auto-graded scores for objective questions
    $answers = json_decode($submission['answers'], true) ?: [];
    foreach ($questions as $qid => &$question) {
        if (!in_array($question['question_type'], ['essay', 'short_answer', 'code', 'fill_blanks'])) {
            // Auto-grade objective questions
            $studentAnswer = $answers[$qid] ?? null;
            $question['earned_points'] = calculateQuestionScore($question, $studentAnswer);
        }
    }

    // Format student name
    $studentDisplayName = $submission['first_name'] && $submission['last_name']
        ? $submission['first_name'] . ' ' . $submission['last_name']
        : $submission['student_name'];

    $submission['student_name'] = $studentDisplayName;
    $submission['attempt_id'] = $submission['id'];

    echo json_encode([
        'success' => true,
        'submission' => $submission,
        'questions' => array_values($questions)
    ]);

} catch (Exception $e) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}

function calculateQuestionScore($question, $studentAnswer) {
    if (!$studentAnswer) return 0;

    switch ($question['question_type']) {
        case 'mcq_single':
        case 'true_false':
            foreach ($question['options'] as $option) {
                if ($option['id'] == $studentAnswer && $option['is_correct']) {
                    return $question['points'];
                }
            }
            return 0;

        case 'mcq_multiple':
            if (is_array($studentAnswer)) {
                $correctOptions = array_filter($question['options'], fn($opt) => $opt['is_correct']);
                $selectedCorrect = 0;
                $totalCorrect = count($correctOptions);

                foreach ($studentAnswer as $selectedId) {
                    foreach ($correctOptions as $correctOption) {
                        if ($correctOption['id'] == $selectedId) {
                            $selectedCorrect++;
                            break;
                        }
                    }
                }

                return $totalCorrect > 0 ? ($selectedCorrect / $totalCorrect) * $question['points'] : 0;
            }
            return 0;

        case 'matching':
            if (is_array($studentAnswer)) {
                $correctMatches = 0;
                $totalMatches = 0;

                foreach ($question['options'] as $option) {
                    if ($option['is_correct']) {
                        $totalMatches++;
                        if (isset($studentAnswer[$option['id']]) &&
                            $studentAnswer[$option['id']] == $option['id']) {
                            $correctMatches++;
                        }
                    }
                }

                return $totalMatches > 0 ? ($correctMatches / $totalMatches) * $question['points'] : 0;
            }
            return 0;

        default:
            return 0;
    }
}
?>