# Question Translations - Usage Guide

This guide demonstrates how to use the multilingual question translation system with CKEditor HTML content.

## Table of Contents
1. [Running the Migration](#running-the-migration)
2. [Creating Translations](#creating-translations)
3. [Retrieving Translations](#retrieving-translations)
4. [Checking Translation Existence](#checking-translation-existence)
5. [Getting Available Languages](#getting-available-languages)
6. [Advanced Usage](#advanced-usage)
7. [API Controller Examples](#api-controller-examples)

---

## Running the Migration

First, run the migration to create the `question_translations` table:

```bash
php artisan migrate
```

This will create the table with all indexes and foreign key constraints.

---

## Creating Translations

### Example 1: Create a Manual Hindi Translation

```php
use App\Models\Question;
use App\Models\QuestionTranslation;

// Get the question
$question = Question::find(1);

// Create Hindi translation with CKEditor HTML
$translation = new QuestionTranslation([
    'question_id' => $question->id,
    'language_code' => 'hi',
    'question_text' => '<p>निम्नलिखित में से कौन सा <strong>सही</strong> है?</p>',
    'option_a' => '<p>विकल्प A</p>',
    'option_b' => '<p>विकल्प B</p>',
    'option_c' => '<p>विकल्प C</p>',
    'option_d' => '<p>विकल्प D</p>',
    'solution' => '<p>हल: <em>यह सही उत्तर है</em> क्योंकि $x^2 + y^2 = z^2$</p>',
    'translated_by' => auth()->id(), // Current logged-in teacher
    'translation_method' => 'manual'
]);

$translation->save();

// Character count is automatically calculated
echo "Translation created with {$translation->character_count} characters";
```

### Example 2: Create Multiple Translations Using Relationship

```php
$question = Question::find(1);

// Create Marathi translation
$question->translations()->create([
    'language_code' => 'mr',
    'question_text' => '<p>खालीलपैकी <strong>योग्य</strong> कोणते आहे?</p>',
    'option_a' => '<p>पर्याय A</p>',
    'option_b' => '<p>पर्याय B</p>',
    'option_c' => '<p>पर्याय C</p>',
    'option_d' => '<p>पर्याय D</p>',
    'solution' => '<p>उत्तर: <em>हे योग्य उत्तर आहे</em></p>',
    'translated_by' => auth()->id(),
    'translation_method' => 'manual'
]);

// Create Tamil translation
$question->translations()->create([
    'language_code' => 'ta',
    'question_text' => '<p>பின்வருவனவற்றுள் எது <strong>சரியானது</strong>?</p>',
    'option_a' => '<p>விருப்பம் A</p>',
    'option_b' => '<p>விருப்பம் B</p>',
    'option_c' => '<p>விருப்பம் C</p>',
    'option_d' => '<p>விருப்பம் D</p>',
    'solution' => null, // No solution translated yet
    'translated_by' => auth()->id(),
    'translation_method' => 'google_api'
]);
```

### Example 3: Batch Translation with Google API

```php
$questions = Question::whereIn('id', [1, 2, 3, 4, 5])->get();
$translatorId = auth()->id();

foreach ($questions as $question) {
    // Call Google Translate API (pseudo-code)
    $translatedData = GoogleTranslateService::translate($question, 'gu');

    $question->translations()->create([
        'language_code' => 'gu',
        'question_text' => $translatedData['question_text'],
        'option_a' => $translatedData['option_a'],
        'option_b' => $translatedData['option_b'],
        'option_c' => $translatedData['option_c'],
        'option_d' => $translatedData['option_d'],
        'solution' => $translatedData['solution'] ?? null,
        'translated_by' => $translatorId,
        'translation_method' => 'batch',
        'character_count' => $translatedData['character_count'] ?? 0
    ]);
}

echo "Batch translated " . $questions->count() . " questions to Gujarati";
```

---

## Retrieving Translations

### Example 4: Get Translation for Display

```php
$question = Question::find(1);

// Get Hindi translation
$hindiTranslation = $question->getTranslation('hi');

if ($hindiTranslation) {
    echo $hindiTranslation->question_text; // Outputs CKEditor HTML
    echo $hindiTranslation->option_a;
    echo $hindiTranslation->solution;

    // Access metadata
    echo "Translated by: " . $hindiTranslation->translator->name;
    echo "Method: " . $hindiTranslation->translation_method;
    echo "Characters: " . $hindiTranslation->character_count;
}
```

### Example 5: Load Question with Specific Translation

```php
// Load question with Hindi translation (eager loading)
$question = Question::withTranslation('hi')->find(1);

// Access the translation
$hindiTranslation = $question->translations->first();

if ($hindiTranslation) {
    return response()->json([
        'question_id' => $question->id,
        'language' => 'hi',
        'content' => [
            'question_text' => $hindiTranslation->question_text,
            'option_a' => $hindiTranslation->option_a,
            'option_b' => $hindiTranslation->option_b,
            'option_c' => $hindiTranslation->option_c,
            'option_d' => $hindiTranslation->option_d,
            'solution' => $hindiTranslation->solution,
        ]
    ]);
}
```

### Example 6: Load Multiple Questions with All Translations

```php
// Load questions with all translations
$questions = Question::withTranslations()
    ->where('category_id', 5)
    ->get();

foreach ($questions as $question) {
    echo "Question ID: {$question->id}\n";
    echo "Available in " . $question->translationsCount() . " languages\n";

    foreach ($question->translations as $translation) {
        echo "  - {$translation->language_code}: {$translation->character_count} chars\n";
    }
}
```

---

## Checking Translation Existence

### Example 7: Check Before Creating Translation

```php
$question = Question::find(1);
$languageCode = 'te'; // Telugu

// Check if translation already exists
if ($question->hasTranslation($languageCode)) {
    echo "Translation already exists for {$languageCode}";

    // Update existing translation
    $translation = $question->getTranslation($languageCode);
    $translation->update([
        'solution' => '<p>Updated solution with LaTeX: $E = mc^2$</p>'
    ]);
} else {
    // Create new translation
    $question->translations()->create([
        'language_code' => $languageCode,
        'question_text' => '<p>Telugu question text</p>',
        'option_a' => '<p>Option A</p>',
        'option_b' => '<p>Option B</p>',
        'option_c' => '<p>Option C</p>',
        'option_d' => '<p>Option D</p>',
        'solution' => null,
        'translated_by' => auth()->id(),
        'translation_method' => 'manual'
    ]);
}
```

### Example 8: Using getOrNewTranslation Helper

```php
$question = Question::find(1);

// Get existing or create new (not saved)
$translation = $question->getOrNewTranslation('bn', auth()->id());

// Populate fields
$translation->question_text = '<p>Bengali question text</p>';
$translation->option_a = '<p>বিকল্প A</p>';
$translation->option_b = '<p>বিকল্প B</p>';
$translation->option_c = '<p>বিকল্প C</p>';
$translation->option_d = '<p>বিকল্প D</p>';
$translation->solution = '<p>Solution: $\\frac{a}{b}$</p>';
$translation->translation_method = 'manual';

// Save it
$translation->save();
```

---

## Getting Available Languages

### Example 9: List All Available Languages

```php
$question = Question::find(1);

// Get array of language codes
$languages = $question->availableLanguages();

// Output: ['en', 'hi', 'mr', 'ta']
print_r($languages);

// Check if specific language is available
if (in_array('hi', $languages)) {
    echo "Hindi translation is available";
}
```

### Example 10: Display Language Options in UI

```php
$question = Question::find(1);
$availableLanguages = $question->availableLanguages();

// Language names mapping
$languageNames = [
    'en' => 'English',
    'hi' => 'हिन्दी (Hindi)',
    'mr' => 'मराठी (Marathi)',
    'ta' => 'தமிழ் (Tamil)',
    'te' => 'తెలుగు (Telugu)',
    'gu' => 'ગુજરાતી (Gujarati)',
    'bn' => 'বাংলা (Bengali)',
];

$languageOptions = [];
foreach ($availableLanguages as $code) {
    $languageOptions[] = [
        'code' => $code,
        'name' => $languageNames[$code] ?? $code
    ];
}

return response()->json([
    'question_id' => $question->id,
    'available_languages' => $languageOptions
]);
```

---

## Advanced Usage

### Example 11: Query Translations with Scopes

```php
// Get all Hindi translations
$hindiTranslations = QuestionTranslation::language('hi')->get();

// Get manual translations only
$manualTranslations = QuestionTranslation::byMethod('manual')->get();

// Get translations by specific translator
$myTranslations = QuestionTranslation::byTranslator(auth()->id())->get();

// Combine scopes
$myHindiManualTranslations = QuestionTranslation::language('hi')
    ->byMethod('manual')
    ->byTranslator(auth()->id())
    ->get();
```

### Example 12: Analytics - Translation Statistics

```php
use App\Models\QuestionTranslation;
use Illuminate\Support\Facades\DB;

// Get translation count by language
$languageStats = QuestionTranslation::select('language_code', DB::raw('count(*) as count'))
    ->groupBy('language_code')
    ->get();

// Get translation count by method
$methodStats = QuestionTranslation::select('translation_method', DB::raw('count(*) as count'))
    ->groupBy('translation_method')
    ->get();

// Get top translators
$topTranslators = QuestionTranslation::select('translated_by', DB::raw('count(*) as translations_count'))
    ->with('translator')
    ->groupBy('translated_by')
    ->orderBy('translations_count', 'desc')
    ->limit(10)
    ->get();

// Total characters translated
$totalCharacters = QuestionTranslation::sum('character_count');

return response()->json([
    'language_stats' => $languageStats,
    'method_stats' => $methodStats,
    'top_translators' => $topTranslators,
    'total_characters' => $totalCharacters
]);
```

### Example 13: Cascade Delete Behavior

```php
// When a question is deleted, all its translations are automatically deleted
$question = Question::find(1);

// This will also delete all translations due to cascade
$question->delete();

// Verify translations are gone
$translationsCount = QuestionTranslation::where('question_id', 1)->count();
echo "Remaining translations: {$translationsCount}"; // Should be 0
```

---

## API Controller Examples

### Example 14: Controller for Storing Translations

```php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Question;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class QuestionTranslationController extends Controller
{
    /**
     * Store a new translation for a question.
     */
    public function store(Request $request, $questionId)
    {
        $question = Question::findOrFail($questionId);

        $validated = $request->validate([
            'language_code' => [
                'required',
                'string',
                'max:10',
                Rule::in(['hi', 'en', 'mr', 'ta', 'te', 'gu', 'bn']),
                // Ensure unique translation per question
                Rule::unique('question_translations')->where(function ($query) use ($questionId) {
                    return $query->where('question_id', $questionId);
                })
            ],
            'question_text' => 'required|string',
            'option_a' => 'required|string',
            'option_b' => 'required|string',
            'option_c' => 'required|string',
            'option_d' => 'required|string',
            'solution' => 'nullable|string',
            'translation_method' => ['required', Rule::in(['manual', 'google_api', 'batch'])],
        ]);

        $translation = $question->translations()->create([
            ...$validated,
            'translated_by' => auth()->id(),
        ]);

        return response()->json([
            'message' => 'Translation created successfully',
            'translation' => $translation,
            'character_count' => $translation->character_count
        ], 201);
    }

    /**
     * Get translation for a specific language.
     */
    public function show($questionId, $languageCode)
    {
        $question = Question::findOrFail($questionId);

        $translation = $question->getTranslation($languageCode);

        if (!$translation) {
            return response()->json([
                'message' => 'Translation not found for this language'
            ], 404);
        }

        return response()->json([
            'translation' => $translation,
            'translator' => $translation->translator->name,
            'created_at' => $translation->created_at->format('Y-m-d H:i:s')
        ]);
    }

    /**
     * Update existing translation.
     */
    public function update(Request $request, $questionId, $languageCode)
    {
        $question = Question::findOrFail($questionId);
        $translation = $question->getTranslation($languageCode);

        if (!$translation) {
            return response()->json([
                'message' => 'Translation not found'
            ], 404);
        }

        $validated = $request->validate([
            'question_text' => 'sometimes|required|string',
            'option_a' => 'sometimes|required|string',
            'option_b' => 'sometimes|required|string',
            'option_c' => 'sometimes|required|string',
            'option_d' => 'sometimes|required|string',
            'solution' => 'nullable|string',
        ]);

        $translation->update($validated);

        return response()->json([
            'message' => 'Translation updated successfully',
            'translation' => $translation->fresh(),
            'character_count' => $translation->character_count
        ]);
    }

    /**
     * Get all available languages for a question.
     */
    public function availableLanguages($questionId)
    {
        $question = Question::findOrFail($questionId);

        return response()->json([
            'question_id' => $question->id,
            'available_languages' => $question->availableLanguages(),
            'translations_count' => $question->translationsCount()
        ]);
    }
}
```

### Example 15: Frontend Display Controller

```php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Question;
use Illuminate\Http\Request;

class QuestionDisplayController extends Controller
{
    /**
     * Get question with translation for frontend display.
     */
    public function getQuestion(Request $request, $questionId)
    {
        $languageCode = $request->input('language', 'en');

        $question = Question::findOrFail($questionId);

        // Try to get translation
        $translation = $question->getTranslation($languageCode);

        if ($translation) {
            // Return translated version
            return response()->json([
                'id' => $question->id,
                'language' => $languageCode,
                'question_text' => $translation->question_text,
                'option_a' => $translation->option_a,
                'option_b' => $translation->option_b,
                'option_c' => $translation->option_c,
                'option_d' => $translation->option_d,
                'solution' => $translation->solution,
                'is_translated' => true,
                'available_languages' => $question->availableLanguages()
            ]);
        }

        // Fallback to original question (assuming it has these fields)
        return response()->json([
            'id' => $question->id,
            'language' => 'original',
            'question_text' => $question->question_text ?? $question->question,
            'is_translated' => false,
            'available_languages' => $question->availableLanguages()
        ]);
    }

    /**
     * Get multiple questions with translations.
     */
    public function getQuestions(Request $request)
    {
        $languageCode = $request->input('language', 'en');
        $questionIds = $request->input('question_ids', []);

        $questions = Question::whereIn('id', $questionIds)
            ->withTranslation($languageCode)
            ->get();

        $result = $questions->map(function ($question) use ($languageCode) {
            $translation = $question->translations->first();

            return [
                'id' => $question->id,
                'language' => $languageCode,
                'has_translation' => $translation !== null,
                'content' => $translation ? [
                    'question_text' => $translation->question_text,
                    'option_a' => $translation->option_a,
                    'option_b' => $translation->option_b,
                    'option_c' => $translation->option_c,
                    'option_d' => $translation->option_d,
                    'solution' => $translation->solution,
                ] : null
            ];
        });

        return response()->json([
            'questions' => $result,
            'language' => $languageCode
        ]);
    }
}
```

---

## Important Notes

1. **CKEditor HTML Preservation**: All fields store complete CKEditor HTML including tags like `<p>`, `<strong>`, `<em>`, etc. Never strip HTML tags.

2. **LaTeX Support**: LaTeX formulas (e.g., `$x^2$`) are preserved within the HTML content.

3. **Character Count**: Automatically calculated on save, strips HTML for accurate counting (for cost tracking).

4. **Language Codes**: Always converted to lowercase automatically.

5. **Duplicate Prevention**: Composite unique index prevents duplicate translations for the same question and language.

6. **Cascade Delete**: When a question is deleted, all its translations are automatically removed.

7. **Foreign Key Constraints**:
   - `translated_by` uses RESTRICT to prevent deleting users who have translations
   - `question_id` uses CASCADE to auto-delete translations when question is deleted

---

## Testing the Implementation

Run these commands to test:

```bash
# Run migration
php artisan migrate

# Test in Tinker
php artisan tinker

# Then test:
$q = Question::first();
$q->translations()->create([
    'language_code' => 'hi',
    'question_text' => '<p>Test</p>',
    'option_a' => '<p>A</p>',
    'option_b' => '<p>B</p>',
    'option_c' => '<p>C</p>',
    'option_d' => '<p>D</p>',
    'translated_by' => 1,
    'translation_method' => 'manual'
]);
```

---

## Summary

This implementation provides:
- ✅ Complete migration with indexes and foreign keys
- ✅ QuestionTranslation model with automatic character counting
- ✅ Question model with helper methods
- ✅ Relationship support for easy querying
- ✅ CKEditor HTML and LaTeX preservation
- ✅ Multiple translation methods tracking
- ✅ Translator attribution
- ✅ Cost tracking via character count
- ✅ Comprehensive API examples

You're now ready to implement multilingual support for your questions!
