"""
Tests für RelevanceProfile Model.
"""

import pytest
from datetime import datetime

from alerts_agent.models.relevance_profile import RelevanceProfile, PriorityItem


class TestPriorityItem:
    """Tests für PriorityItem."""

    def test_create_minimal(self):
        """Test minimale Erstellung."""
        item = PriorityItem(label="Test Topic")

        assert item.label == "Test Topic"
        assert item.weight == 0.5  # Default
        assert item.keywords == []
        assert item.description is None

    def test_create_full(self):
        """Test vollständige Erstellung."""
        item = PriorityItem(
            label="Inklusion",
            weight=0.9,
            keywords=["inklusiv", "Förderbedarf"],
            description="Inklusive Bildung in Schulen",
        )

        assert item.label == "Inklusion"
        assert item.weight == 0.9
        assert "inklusiv" in item.keywords
        assert item.description is not None

    def test_to_dict(self):
        """Test Serialisierung."""
        item = PriorityItem(label="Test", weight=0.8, keywords=["kw1", "kw2"])
        data = item.to_dict()

        assert data["label"] == "Test"
        assert data["weight"] == 0.8
        assert data["keywords"] == ["kw1", "kw2"]

    def test_from_dict(self):
        """Test Deserialisierung."""
        data = {"label": "Test", "weight": 0.7, "keywords": ["test"]}
        item = PriorityItem.from_dict(data)

        assert item.label == "Test"
        assert item.weight == 0.7


class TestRelevanceProfile:
    """Tests für RelevanceProfile."""

    def test_create_empty(self):
        """Test leeres Profil."""
        profile = RelevanceProfile()

        assert profile.id is not None
        assert profile.priorities == []
        assert profile.exclusions == []
        assert profile.positive_examples == []
        assert profile.negative_examples == []

    def test_add_priority(self):
        """Test Priorität hinzufügen."""
        profile = RelevanceProfile()
        profile.add_priority("Datenschutz", weight=0.85)

        assert len(profile.priorities) == 1
        assert profile.priorities[0].label == "Datenschutz"
        assert profile.priorities[0].weight == 0.85

    def test_add_exclusion(self):
        """Test Ausschluss hinzufügen."""
        profile = RelevanceProfile()
        profile.add_exclusion("Stellenanzeige")
        profile.add_exclusion("Werbung")

        assert len(profile.exclusions) == 2
        assert "Stellenanzeige" in profile.exclusions
        assert "Werbung" in profile.exclusions

    def test_no_duplicate_exclusions(self):
        """Test keine doppelten Ausschlüsse."""
        profile = RelevanceProfile()
        profile.add_exclusion("Test")
        profile.add_exclusion("Test")

        assert len(profile.exclusions) == 1

    def test_add_positive_example(self):
        """Test positives Beispiel hinzufügen."""
        profile = RelevanceProfile()
        profile.add_positive_example(
            title="Gutes Beispiel",
            url="https://example.com",
            reason="Relevant für Thema X",
        )

        assert len(profile.positive_examples) == 1
        assert profile.positive_examples[0]["title"] == "Gutes Beispiel"
        assert profile.positive_examples[0]["reason"] == "Relevant für Thema X"

    def test_add_negative_example(self):
        """Test negatives Beispiel hinzufügen."""
        profile = RelevanceProfile()
        profile.add_negative_example(
            title="Schlechtes Beispiel",
            url="https://example.com",
            reason="Werbung",
        )

        assert len(profile.negative_examples) == 1

    def test_examples_limited_to_20(self):
        """Test Beispiele auf 20 begrenzt."""
        profile = RelevanceProfile()

        for i in range(25):
            profile.add_positive_example(
                title=f"Example {i}",
                url=f"https://example.com/{i}",
            )

        assert len(profile.positive_examples) == 20
        # Sollte die neuesten behalten
        assert "Example 24" in profile.positive_examples[-1]["title"]

    def test_update_from_feedback_positive(self):
        """Test Feedback Update (positiv)."""
        profile = RelevanceProfile()
        profile.update_from_feedback(
            alert_title="Relevant Article",
            alert_url="https://example.com",
            is_relevant=True,
            reason="Sehr relevant",
        )

        assert len(profile.positive_examples) == 1
        assert profile.total_kept == 1
        assert profile.total_scored == 1

    def test_update_from_feedback_negative(self):
        """Test Feedback Update (negativ)."""
        profile = RelevanceProfile()
        profile.update_from_feedback(
            alert_title="Irrelevant Article",
            alert_url="https://example.com",
            is_relevant=False,
            reason="Werbung",
        )

        assert len(profile.negative_examples) == 1
        assert profile.total_dropped == 1
        assert profile.total_scored == 1


class TestPromptContext:
    """Tests für Prompt-Kontext Generierung."""

    def test_empty_profile_prompt(self):
        """Test Prompt für leeres Profil."""
        profile = RelevanceProfile()
        context = profile.get_prompt_context()

        assert "Relevanzprofil" in context
        # Leeres Profil hat keine Prioritäten/Ausschlüsse
        assert "Prioritäten" not in context

    def test_priorities_in_prompt(self):
        """Test Prioritäten im Prompt."""
        profile = RelevanceProfile()
        profile.add_priority("Inklusion", weight=0.9, description="Sehr wichtig")

        context = profile.get_prompt_context()

        assert "Inklusion" in context
        assert "Sehr wichtig" in context

    def test_exclusions_in_prompt(self):
        """Test Ausschlüsse im Prompt."""
        profile = RelevanceProfile()
        profile.add_exclusion("Stellenanzeige")
        profile.add_exclusion("Werbung")

        context = profile.get_prompt_context()

        assert "Stellenanzeige" in context
        assert "Werbung" in context
        assert "Ausschlüsse" in context

    def test_examples_in_prompt(self):
        """Test Beispiele im Prompt."""
        profile = RelevanceProfile()
        profile.add_positive_example(
            title="Gutes Beispiel",
            url="https://example.com",
            reason="Relevant",
        )

        context = profile.get_prompt_context()

        assert "Gutes Beispiel" in context
        assert "relevante Alerts" in context


class TestDefaultEducationProfile:
    """Tests für das Standard-Bildungsprofil."""

    def test_create_default_profile(self):
        """Test Default-Profil Erstellung."""
        profile = RelevanceProfile.create_default_education_profile()

        assert len(profile.priorities) > 0
        assert len(profile.exclusions) > 0
        assert len(profile.policies) > 0

    def test_default_priorities(self):
        """Test Default-Prioritäten enthalten Bildungsthemen."""
        profile = RelevanceProfile.create_default_education_profile()

        labels = [p.label for p in profile.priorities]

        assert "Inklusion" in labels
        assert "Datenschutz Schule" in labels
        assert "Schulrecht Bayern" in labels

    def test_default_exclusions(self):
        """Test Default-Ausschlüsse."""
        profile = RelevanceProfile.create_default_education_profile()

        assert "Stellenanzeige" in profile.exclusions
        assert "Werbung" in profile.exclusions

    def test_default_policies(self):
        """Test Default-Policies."""
        profile = RelevanceProfile.create_default_education_profile()

        assert profile.policies.get("prefer_german_sources") is True
        assert "max_age_days" in profile.policies


class TestSerialization:
    """Tests für Serialisierung."""

    def test_to_dict(self):
        """Test Konvertierung zu Dict."""
        profile = RelevanceProfile()
        profile.add_priority("Test", weight=0.7)
        profile.add_exclusion("Exclude")

        data = profile.to_dict()

        assert "id" in data
        assert len(data["priorities"]) == 1
        assert "Exclude" in data["exclusions"]
        assert "created_at" in data

    def test_from_dict(self):
        """Test Erstellung aus Dict."""
        data = {
            "id": "test-id",
            "priorities": [{"label": "Test", "weight": 0.8, "keywords": [], "description": None}],
            "exclusions": ["Exclude"],
            "positive_examples": [],
            "negative_examples": [],
            "policies": {"key": "value"},
            "created_at": "2024-01-15T10:00:00",
            "updated_at": "2024-01-15T10:00:00",
            "total_scored": 100,
            "total_kept": 60,
            "total_dropped": 40,
            "accuracy_estimate": None,
        }

        profile = RelevanceProfile.from_dict(data)

        assert profile.id == "test-id"
        assert len(profile.priorities) == 1
        assert profile.total_scored == 100

    def test_round_trip(self):
        """Test Serialisierung/Deserialisierung Roundtrip."""
        original = RelevanceProfile.create_default_education_profile()
        original.add_positive_example("Test", "https://test.com")

        data = original.to_dict()
        restored = RelevanceProfile.from_dict(data)

        assert restored.id == original.id
        assert len(restored.priorities) == len(original.priorities)
        assert len(restored.positive_examples) == len(original.positive_examples)
