<?php
require_once '../config.php';

// Enforce rate limiting on quiz submissions (Max 5 per minute per IP)
checkRateLimit('submit_quiz', 5, 60);

$data = json_decode(file_get_contents("php://input"), true);

if (empty($data['user_id']) || empty($data['quiz_id']) || !isset($data['answers']) || !is_array($data['answers'])) {
    http_response_code(400);
    echo json_encode(["status" => "error", "message" => "All fields (user_id, quiz_id, answers) are required."]);
    exit();
}

$userId = intval($data['user_id']);
$quizId = intval($data['quiz_id']);
$submittedAnswers = $data['answers']; // array of selected option indices (0-3) e.g. [0, 1, 2, 0, 3]
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';

try {
    $db = getDBConnection();

    // 1. Verify user exists
    $stmt = $db->prepare("SELECT id FROM users WHERE id = ? AND is_verified = 1");
    $stmt->execute([$userId]);
    if (!$stmt->fetch()) {
        http_response_code(404);
        echo json_encode(["status" => "error", "message" => "User account not found or unverified."]);
        exit();
    }

    // 2. Verify quiz exists and is active
    $stmt = $db->prepare("SELECT * FROM quizzes WHERE id = ? AND is_active = 1");
    $stmt->execute([$quizId]);
    $quiz = $stmt->fetch();

    if (!$quiz) {
        http_response_code(404);
        echo json_encode(["status" => "error", "message" => "Requested quiz is not active or does not exist."]);
        exit();
    }

    $correctCount = 0;
    $historyToInsert = [];

    // 3. Compare chosen answers against secure DB master keys (elimination: stop at first incorrect)
    foreach ($submittedAnswers as $ans) {
        $qId = isset($ans['question_id']) ? intval($ans['question_id']) : 0;
        $chosenOpt = isset($ans['chosen_option']) ? intval($ans['chosen_option']) : -1;

        if ($qId <= 0 || $chosenOpt < 0) {
            break; // Stop at any invalid entry
        }

        // Fetch correct option index for this question ID from DB
        $stmt = $db->prepare("SELECT correct_option FROM quiz_questions WHERE id = ? AND quiz_id = ?");
        $stmt->execute([$qId, $quizId]);
        $row = $stmt->fetch();

        if ($row && intval($row['correct_option']) === $chosenOpt) {
            $correctCount++;
            $historyToInsert[] = $qId;
        } else {
            if ($row) {
                $historyToInsert[] = $qId;
            }
            break; // Stop counting on first incorrect answer (elimination)
        }
    }

    // 4. Calculate rewards dynamically based on consecutive correct count
    $prizeMap = [
        0 => 0.00,
        1 => 0.00,
        2 => 0.00,
        3 => 0.00,
        4 => 0.00,
        5 => 5000.00,
        6 => 7500.00,
        7 => 10000.00,
        8 => 20000.00,
        9 => 30000.00,
        10 => 40000.00,
        11 => 50000.00,
        12 => 60000.00,
        13 => 70000.00,
        14 => 80000.00,
        15 => 100000.00
    ];
    $rewardEarned = isset($prizeMap[$correctCount]) ? floatval($prizeMap[$correctCount]) : 0.00;

    // Start SQL transaction block
    $db->beginTransaction();

    $balance_before = 0.00;
    $balance_after = 0.00;
    $reference = '';

    if ($rewardEarned > 0) {
        // Lock user wallet to prevent concurrency manipulation
        $stmt = $db->prepare("SELECT balance, today_winnings FROM wallets WHERE user_id = ? FOR UPDATE");
        $stmt->execute([$userId]);
        $wallet = $stmt->fetch();

        if (!$wallet) {
            $balance_before = 0.00;
            $balance_after = $rewardEarned;
            $stmt = $db->prepare("INSERT INTO wallets (user_id, balance, today_winnings) VALUES (?, ?, ?)");
            $stmt->execute([$userId, $balance_after, $rewardEarned]);
        } else {
            $balance_before = floatval($wallet['balance']);
            $balance_after = $balance_before + $rewardEarned;
            $today_winnings_new = floatval($wallet['today_winnings']) + $rewardEarned;

            $stmt = $db->prepare("UPDATE wallets SET balance = ?, today_winnings = ? WHERE user_id = ?");
            $stmt->execute([$balance_after, $today_winnings_new, $userId]);
        }

        // Generate dynamic secure transaction reference
        $reference = uniqid('TXN-QZ' . $quizId . '-', true);

        // Append to Immutable Wallet Transaction Logs
        $stmt = $db->prepare("INSERT INTO wallet_transactions (user_id, action, amount, balance_before, balance_after, reference, ip_address) VALUES (?, 'reward', ?, ?, ?, ?, ?)");
        $stmt->execute([$userId, $rewardEarned, $balance_before, $balance_after, $reference, $ip]);
    }

    // Record question history so they don't repeat
    if (!empty($historyToInsert)) {
        $stmtHist = $db->prepare("INSERT IGNORE INTO user_question_history (user_id, question_id) VALUES (?, ?)");
        foreach ($historyToInsert as $qId) {
            $stmtHist->execute([$userId, $qId]);
        }
    }

    // Record quiz attempt
    $stmtAtt = $db->prepare("INSERT INTO quiz_attempts (user_id, quiz_id, score, reward_earned) VALUES (?, ?, ?, ?)");
    $stmtAtt->execute([$userId, $quizId, $correctCount, $rewardEarned]);

    // Commit changes securely
    $db->commit();

    echo json_encode([
        "status" => "success",
        "message" => "Quiz submitted successfully! Score calculated and verified.",
        "score" => [
            "correct_answers" => $correctCount,
            "total_questions" => 15,
            "reward_earned" => $rewardEarned
        ],
        "reference" => $reference,
        "new_balance" => $rewardEarned > 0 ? $balance_after : null
    ]);

} catch(Exception $e) {
    if (isset($db) && $db->inTransaction()) {
        $db->rollBack();
    }
    logSecurityError("Quiz Submission failure (User: $userId, Quiz: $quizId): " . $e->getMessage());
    http_response_code(500);
    echo json_encode(["status" => "error", "message" => "Failed to submit quiz score. Security rollback executed."]);
}
