"""
Tests für Worksheets API.

Testet alle Content-Generatoren:
- Multiple Choice
- Cloze (Lückentext)
- Mindmap
- Quiz
"""

import pytest
from fastapi.testclient import TestClient

# Importiere main app
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from main import app

client = TestClient(app)

# Sample text für Tests (mind. 50 Zeichen erforderlich)
SAMPLE_TEXT = """
Die Photosynthese ist ein biologischer Prozess, bei dem Pflanzen, Algen und einige Bakterien
Lichtenergie in chemische Energie umwandeln. Dieser Vorgang findet hauptsächlich in den
Chloroplasten der Pflanzenzellen statt. Dabei werden Kohlendioxid und Wasser unter Verwendung
von Sonnenlicht in Glucose und Sauerstoff umgewandelt. Die Photosynthese ist fundamental für
das Leben auf der Erde, da sie Sauerstoff produziert und die Basis der Nahrungskette bildet.
Pflanzen nutzen die produzierte Glucose als Energiequelle für ihr Wachstum.
"""

SHORT_TEXT = "Zu kurz"


class TestMultipleChoiceGeneration:
    """Tests für Multiple Choice Generierung."""

    def test_generate_mc_success(self):
        """Testet erfolgreiche MC-Generierung."""
        response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SAMPLE_TEXT,
                "num_questions": 3,
                "difficulty": "medium",
                "topic": "Photosynthese",
                "subject": "Biologie"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert data["content"] is not None
        assert data["content"]["content_type"] == "multiple_choice"
        assert "questions" in data["content"]["data"]

    def test_generate_mc_with_h5p(self):
        """Testet H5P-Export für MC."""
        response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SAMPLE_TEXT,
                "num_questions": 2,
                "difficulty": "easy"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"]["h5p_format"] is not None
        assert data["content"]["h5p_format"]["library"] == "H5P.MultiChoice"

    def test_generate_mc_text_too_short(self):
        """Testet Fehler bei zu kurzem Text."""
        response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SHORT_TEXT,
                "num_questions": 3
            }
        )

        # Pydantic Validation sollte fehlschlagen
        assert response.status_code == 422

    def test_generate_mc_difficulty_levels(self):
        """Testet verschiedene Schwierigkeitsgrade."""
        for difficulty in ["easy", "medium", "hard"]:
            response = client.post(
                "/api/worksheets/generate/multiple-choice",
                json={
                    "source_text": SAMPLE_TEXT,
                    "num_questions": 2,
                    "difficulty": difficulty
                }
            )

            assert response.status_code == 200
            data = response.json()
            assert data["content"]["difficulty"] == difficulty


class TestClozeGeneration:
    """Tests für Lückentext-Generierung."""

    def test_generate_cloze_fill_in(self):
        """Testet Fill-in Lückentext."""
        response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 3,
                "cloze_type": "fill_in",
                "topic": "Photosynthese"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert data["content"]["content_type"] == "cloze"
        assert "gaps" in data["content"]["data"]
        assert "text_with_gaps" in data["content"]["data"]

    def test_generate_cloze_drag_drop(self):
        """Testet Drag-Drop Lückentext."""
        response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 4,
                "cloze_type": "drag_drop"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"]["data"]["cloze_type"] == "drag_drop"

    def test_generate_cloze_dropdown(self):
        """Testet Dropdown Lückentext."""
        response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 3,
                "cloze_type": "dropdown"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"]["data"]["cloze_type"] == "dropdown"

    def test_generate_cloze_h5p_format(self):
        """Testet H5P-Export für Cloze."""
        response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 3
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"]["h5p_format"]["library"] == "H5P.Blanks"


class TestMindmapGeneration:
    """Tests für Mindmap-Generierung."""

    def test_generate_mindmap_success(self):
        """Testet erfolgreiche Mindmap-Generierung."""
        response = client.post(
            "/api/worksheets/generate/mindmap",
            json={
                "source_text": SAMPLE_TEXT,
                "topic": "Photosynthese",
                "max_depth": 3
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert data["content"]["content_type"] == "mindmap"
        assert "mindmap" in data["content"]["data"]
        assert "mermaid" in data["content"]["data"]
        assert "json_tree" in data["content"]["data"]

    def test_generate_mindmap_no_h5p(self):
        """Testet dass Mindmaps kein H5P-Format haben."""
        response = client.post(
            "/api/worksheets/generate/mindmap",
            json={
                "source_text": SAMPLE_TEXT,
                "max_depth": 2
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["content"]["h5p_format"] is None

    def test_generate_mindmap_structure(self):
        """Testet Mindmap-Struktur."""
        response = client.post(
            "/api/worksheets/generate/mindmap",
            json={
                "source_text": SAMPLE_TEXT,
                "max_depth": 3
            }
        )

        data = response.json()
        mindmap = data["content"]["data"]["mindmap"]

        assert "root" in mindmap
        assert "title" in mindmap
        assert "total_nodes" in mindmap
        assert mindmap["root"]["level"] == 0


class TestQuizGeneration:
    """Tests für Quiz-Generierung."""

    def test_generate_quiz_true_false(self):
        """Testet True/False Quiz."""
        response = client.post(
            "/api/worksheets/generate/quiz",
            json={
                "source_text": SAMPLE_TEXT,
                "quiz_types": ["true_false"],
                "num_items": 3
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert "questions" in data["content"]["data"]
        # All questions should be of type true_false
        questions = data["content"]["data"]["questions"]
        assert len(questions) > 0
        assert all(q["type"] == "true_false" for q in questions)

    def test_generate_quiz_matching(self):
        """Testet Matching Quiz mit definitionsreichem Text."""
        # Text with clear definition patterns for matching extraction
        definition_text = """
        Photosynthese ist der Prozess der Umwandlung von Lichtenergie in chemische Energie.
        Chloroplasten bezeichnet die Zellorganellen, in denen die Photosynthese stattfindet.
        Glucose bedeutet Traubenzucker, ein einfacher Zucker.
        ATP: Adenosintriphosphat, der universelle Energietraeger der Zellen.
        Chlorophyll ist der gruene Farbstoff, der Licht absorbiert.
        """
        response = client.post(
            "/api/worksheets/generate/quiz",
            json={
                "source_text": definition_text,
                "quiz_types": ["matching"],
                "num_items": 3
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert "questions" in data["content"]["data"]
        # All questions should be of type matching
        questions = data["content"]["data"]["questions"]
        assert len(questions) > 0
        assert all(q["type"] == "matching" for q in questions)

    def test_generate_quiz_combined(self):
        """Testet kombiniertes Quiz mit mehreren Typen."""
        response = client.post(
            "/api/worksheets/generate/quiz",
            json={
                "source_text": SAMPLE_TEXT,
                "quiz_types": ["true_false", "matching", "sorting"],
                "num_items": 2,
                "difficulty": "medium"
            }
        )

        assert response.status_code == 200
        data = response.json()
        quiz_data = data["content"]["data"]

        assert "questions" in quiz_data
        assert "quiz_types" in quiz_data
        # Should have questions from multiple types
        question_types = set(q["type"] for q in quiz_data["questions"])
        assert len(question_types) >= 1  # At least one type should have generated questions


class TestBatchGeneration:
    """Tests für Batch-Generierung."""

    def test_batch_generate_multiple_types(self):
        """Testet Generierung mehrerer Content-Typen."""
        response = client.post(
            "/api/worksheets/generate/batch",
            json={
                "source_text": SAMPLE_TEXT,
                "content_types": ["multiple_choice", "cloze"],
                "topic": "Photosynthese",
                "difficulty": "medium"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert len(data["contents"]) == 2

        content_types = [c["content_type"] for c in data["contents"]]
        assert "multiple_choice" in content_types
        assert "cloze" in content_types

    def test_batch_generate_all_types(self):
        """Testet Generierung aller Content-Typen."""
        response = client.post(
            "/api/worksheets/generate/batch",
            json={
                "source_text": SAMPLE_TEXT,
                "content_types": ["multiple_choice", "cloze", "mindmap", "quiz"],
                "topic": "Test"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert len(data["contents"]) == 4

    def test_batch_generate_partial_failure(self):
        """Testet Batch mit unbekanntem Typ."""
        response = client.post(
            "/api/worksheets/generate/batch",
            json={
                "source_text": SAMPLE_TEXT,
                "content_types": ["multiple_choice", "unknown_type"],
                "topic": "Test"
            }
        )

        assert response.status_code == 200
        data = response.json()
        assert data["success"] is True
        assert len(data["contents"]) == 1
        assert len(data["errors"]) == 1
        assert "unknown_type" in data["errors"][0]


class TestContentManagement:
    """Tests für Content-Verwaltung."""

    def test_get_content(self):
        """Testet Abrufen von gespeichertem Content."""
        # Erst generieren
        gen_response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SAMPLE_TEXT,
                "num_questions": 2
            }
        )
        content_id = gen_response.json()["content"]["id"]

        # Dann abrufen
        get_response = client.get(f"/api/worksheets/content/{content_id}")

        assert get_response.status_code == 200
        data = get_response.json()
        assert data["content"]["id"] == content_id

    def test_get_content_not_found(self):
        """Testet Fehler bei nicht vorhandenem Content."""
        response = client.get("/api/worksheets/content/nonexistent-id")
        assert response.status_code == 404

    def test_get_content_h5p(self):
        """Testet H5P-Format Abruf."""
        # Erst generieren
        gen_response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SAMPLE_TEXT,
                "num_questions": 2
            }
        )
        content_id = gen_response.json()["content"]["id"]

        # H5P abrufen
        h5p_response = client.get(f"/api/worksheets/content/{content_id}/h5p")

        assert h5p_response.status_code == 200
        data = h5p_response.json()
        assert "library" in data
        assert "params" in data

    def test_delete_content(self):
        """Testet Löschen von Content."""
        # Erst generieren
        gen_response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 3
            }
        )
        content_id = gen_response.json()["content"]["id"]

        # Dann löschen
        del_response = client.delete(f"/api/worksheets/content/{content_id}")
        assert del_response.status_code == 200
        assert del_response.json()["status"] == "deleted"

        # Prüfen dass gelöscht
        get_response = client.get(f"/api/worksheets/content/{content_id}")
        assert get_response.status_code == 404


class TestMetaEndpoints:
    """Tests für Meta-Endpoints."""

    def test_list_content_types(self):
        """Testet Auflistung der Content-Typen."""
        response = client.get("/api/worksheets/types")

        assert response.status_code == 200
        data = response.json()
        assert "content_types" in data
        assert len(data["content_types"]) == 4

        type_names = [t["type"] for t in data["content_types"]]
        assert "multiple_choice" in type_names
        assert "cloze" in type_names
        assert "mindmap" in type_names
        assert "quiz" in type_names

    def test_get_generation_history(self):
        """Testet Generierungs-Historie."""
        # Erst etwas generieren
        client.post(
            "/api/worksheets/generate/mindmap",
            json={
                "source_text": SAMPLE_TEXT,
                "topic": "History Test"
            }
        )

        response = client.get("/api/worksheets/history?limit=5")

        assert response.status_code == 200
        data = response.json()
        assert "total" in data
        assert "contents" in data
        assert data["total"] >= 1


class TestGeneratorIntegration:
    """Tests für Generator-Integration."""

    def test_mc_generator_output_format(self):
        """Testet MC-Generator Output-Format."""
        response = client.post(
            "/api/worksheets/generate/multiple-choice",
            json={
                "source_text": SAMPLE_TEXT,
                "num_questions": 2
            }
        )

        data = response.json()
        questions = data["content"]["data"]["questions"]

        for q in questions:
            assert "question" in q
            assert "options" in q
            assert len(q["options"]) == 4
            assert "difficulty" in q

            # Genau eine richtige Antwort
            correct_count = sum(1 for opt in q["options"] if opt["is_correct"])
            assert correct_count == 1

    def test_cloze_generator_gap_format(self):
        """Testet Cloze-Generator Gap-Format."""
        response = client.post(
            "/api/worksheets/generate/cloze",
            json={
                "source_text": SAMPLE_TEXT,
                "num_gaps": 3
            }
        )

        data = response.json()
        gaps = data["content"]["data"]["gaps"]

        for gap in gaps:
            assert "position" in gap
            assert "answer" in gap
            assert "alternatives" in gap
            assert "distractors" in gap

    def test_mindmap_generator_node_format(self):
        """Testet Mindmap-Generator Node-Format."""
        response = client.post(
            "/api/worksheets/generate/mindmap",
            json={
                "source_text": SAMPLE_TEXT,
                "max_depth": 3
            }
        )

        data = response.json()
        root = data["content"]["data"]["mindmap"]["root"]

        assert "id" in root
        assert "label" in root
        assert "level" in root
        assert "children" in root
        assert "color" in root
