# LMS Question Bank Simulator

This document outlines the usage, functionality, and architectural goals of the **Question Simulator** module developed in the `feat/admin-sub/lms-questions-sub/simulator` branch, which has been merged into the `feat/admin-sub/lms-questions` base branch.

## Overview and Goals

The primary goal of this branch is to introduce an interactive **Question Simulator** feature for administrators. This simulator acts as a testing ground where admins can preview questions exactly as a user or student would see them during an exam. It randomizes questions and instantly evaluates submissions to ensure that all question types, validations, and dynamic scoring logic work as expected.

## Key Features

- **Dynamic Question Loading:** The simulator pulls up to four random parent questions per question type to create a varied testing environment.
- **Interactive UI (AlpineJS):** A seamless, dynamic user interface that handles multiple question formats and instant feedback without requiring full page reloads.
- **Dynamic Scoring Logic:** Real-time scoring evaluation tailored to each specific question type.

### Scoring Logic Implementation

The simulator applies strict, type-specific scoring rules upon submission:

- **Multi-Choice:** Awards partial marks per correct option (1/N, where N is the total number of correct options).
- **Single-Choice:** Awards 1 mark for the correct answer, otherwise 0.
- **Fill-in-the-Blanks:** Awards 1 mark for any attempt, 0 otherwise.
- **Scenario:** Distributes 1 mark across its sub-questions, with further fractional scoring for multi-choice sub-questions within the scenario.

## How to Use the Simulator

1. Navigate to the Question Bank module in the admin dashboard.
2. Click the **"Simulator"** or **"Preview"** button (or access the route directly via `/admin/question/preview-simulator`).
3. You will be presented with a randomized quiz interface containing different question types.
4. Interact with the questions (select options, type answers, etc.) just like a real user.
5. Click **"Submit"** at the bottom of the simulator.
6. The simulator will instantly evaluate your answers using the Dynamic Scoring Logic and display the calculated score.

## File Paths & Core Structure

Here are the essential files introduced or modified in this branch:

| Component | File Path |
| :--- | :--- |
| **Controller** | `app/Http/Controllers/Admin/Question/QuestionController.php` (Added `previewSimulator` method) |
| **Service Logic** | `app/Services/Admin/QuestionService.php` (Added `buildSimulatorPayload` method) |
| **Route** | `routes/admin.php` (Added `question/preview-simulator` GET route) |
| **Blade View** | `resources/views/pages/admin/question/preview-simulator.blade.php` |
| **JavaScript** | `resources/js/admin/question-preview-simulator.js` |

## Service Logic Overview (`QuestionService.php`)

The simulator's dynamic nature relies on transforming raw database records into a unified structure that the Alpine.js frontend can effortlessly parse. This is handled by a suite of protected serialization functions within `app/Services/Admin/QuestionService.php`:

- **`serializeSimulatorQuestions(Collection $questions): array`**
  Iterates over the retrieved parent questions. If a question is a Scenario (contains children), it iterates and serializes its children with dotted numbering (e.g., `1.1`, `1.2`). Otherwise, it serializes the question with standard sequential numbering.

- **`serializeSimulatorQuestion(Question $question, string $number, ?Question $scenario = null): array`**
  The core transformer. It takes a `Question` model and constructs a normalized array containing the ID, calculated display mode, parsed options, correct keys, extracted answers, and cleaned HTML/text. It also injects the scenario context if the question belongs to one.

- **`modeForSimulator(Question $question, array $options, ?string $answer): string`**
  Analyzes the question type and content to dynamically assign an interactive mode (`multi_choice`, `single_choice`, `fill_blank`, or `text`).

- **`optionsForSimulator(Question $question): array`**
  Extracts the `content` JSON array, assigning a sequential alphabetical key (A, B, C...) to each option, while securely casting and standardizing the `isCorrect` boolean flags.

- **`answerForSimulator(Question $question, array $options): ?string`**
  Resolves the exact correct answer(s) as a string for display purposes upon submission, concatenating the option keys with their corresponding text.

- **`hintForSimulator(array $content): ?string`** & **`cleanText($value): string`**
  Utility helpers to safely extract optional hints from the JSON payload and to strip HTML tags using `Str::squish` for clean rendering in specific UI contexts.

## Summary

By integrating the Simulator into the LMS Question Bank, administrators now have a robust tool to validate question configurations, formatting, and scoring distribution instantly without leaving the backend environment.
