"""
Tests für Playbook Service.
"""

import pytest
from datetime import datetime
from llm_gateway.services.playbook_service import (
    PlaybookService,
    Playbook,
    get_playbook_service,
)


class TestPlaybookService:
    """Tests für PlaybookService."""

    def setup_method(self):
        """Setup für jeden Test."""
        self.service = PlaybookService()

    def test_list_playbooks_returns_default_playbooks(self):
        """Test dass Default-Playbooks geladen werden."""
        playbooks = self.service.list_playbooks()
        assert len(playbooks) > 0
        # Prüfe dass bekannte Playbooks existieren
        ids = [p.id for p in playbooks]
        assert "pb_default" in ids
        assert "pb_elternbrief" in ids
        assert "pb_arbeitsblatt" in ids

    def test_list_playbooks_filter_by_status(self):
        """Test Status-Filter."""
        # Alle Default-Playbooks sind published
        published = self.service.list_playbooks(status="published")
        assert len(published) > 0

        # Keine Draft-Playbooks
        drafts = self.service.list_playbooks(status="draft")
        assert len(drafts) == 0

    def test_get_playbook_existing(self):
        """Test Playbook abrufen."""
        playbook = self.service.get_playbook("pb_default")
        assert playbook is not None
        assert playbook.id == "pb_default"
        assert playbook.name == "Standard-Assistent"
        assert len(playbook.system_prompt) > 0

    def test_get_playbook_not_found(self):
        """Test nicht existierendes Playbook."""
        playbook = self.service.get_playbook("non_existent")
        assert playbook is None

    def test_get_system_prompt(self):
        """Test System Prompt abrufen."""
        prompt = self.service.get_system_prompt("pb_elternbrief")
        assert prompt is not None
        assert "Elternbrief" in prompt or "Elternkommunikation" in prompt

    def test_get_system_prompt_not_found(self):
        """Test System Prompt für nicht existierendes Playbook."""
        prompt = self.service.get_system_prompt("non_existent")
        assert prompt is None

    def test_create_playbook(self):
        """Test neues Playbook erstellen."""
        new_playbook = Playbook(
            id="pb_test_new",
            name="Test Playbook",
            description="Ein Test Playbook",
            system_prompt="Du bist ein Test-Assistent.",
            prompt_version="1.0.0",
        )
        created = self.service.create_playbook(new_playbook)
        assert created.id == "pb_test_new"

        # Prüfe dass es abrufbar ist
        retrieved = self.service.get_playbook("pb_test_new")
        assert retrieved is not None
        assert retrieved.name == "Test Playbook"

    def test_create_playbook_duplicate_id(self):
        """Test Playbook mit existierender ID erstellen."""
        duplicate = Playbook(
            id="pb_default",  # Existiert bereits
            name="Duplicate",
            description="Test",
            system_prompt="Test",
            prompt_version="1.0.0",
        )
        with pytest.raises(ValueError):
            self.service.create_playbook(duplicate)

    def test_update_playbook(self):
        """Test Playbook aktualisieren."""
        original = self.service.get_playbook("pb_default")
        original_name = original.name

        updated = self.service.update_playbook(
            "pb_default",
            name="Aktualisierter Name",
        )
        assert updated is not None
        assert updated.name == "Aktualisierter Name"

        # Reset
        self.service.update_playbook("pb_default", name=original_name)

    def test_update_playbook_not_found(self):
        """Test nicht existierendes Playbook aktualisieren."""
        result = self.service.update_playbook("non_existent", name="Test")
        assert result is None

    def test_delete_playbook(self):
        """Test Playbook löschen."""
        # Erst erstellen
        new_playbook = Playbook(
            id="pb_to_delete",
            name="To Delete",
            description="Test",
            system_prompt="Test",
            prompt_version="1.0.0",
        )
        self.service.create_playbook(new_playbook)

        # Dann löschen
        result = self.service.delete_playbook("pb_to_delete")
        assert result is True

        # Prüfen dass gelöscht
        assert self.service.get_playbook("pb_to_delete") is None

    def test_delete_playbook_not_found(self):
        """Test nicht existierendes Playbook löschen."""
        result = self.service.delete_playbook("non_existent")
        assert result is False


class TestPlaybookContent:
    """Tests für Playbook-Inhalte."""

    def setup_method(self):
        """Setup für jeden Test."""
        self.service = PlaybookService()

    def test_elternbrief_playbook_has_guidelines(self):
        """Test dass Elternbrief-Playbook Richtlinien enthält."""
        playbook = self.service.get_playbook("pb_elternbrief")
        assert playbook is not None
        prompt = playbook.system_prompt.lower()
        # Sollte wichtige Richtlinien enthalten
        assert "ton" in prompt or "sprache" in prompt
        assert "brief" in prompt or "eltern" in prompt

    def test_rechtlich_playbook_has_disclaimer(self):
        """Test dass Rechtlich-Playbook Disclaimer enthält."""
        playbook = self.service.get_playbook("pb_rechtlich")
        assert playbook is not None
        prompt = playbook.system_prompt.lower()
        # Sollte Hinweis auf keine Rechtsberatung enthalten
        assert "rechtsberatung" in prompt or "fachanwalt" in prompt

    def test_foerderplan_playbook_mentions_privacy(self):
        """Test dass Förderplan-Playbook Datenschutz erwähnt."""
        playbook = self.service.get_playbook("pb_foerderplan")
        assert playbook is not None
        prompt = playbook.system_prompt.lower()
        # Sollte sensible Daten erwähnen
        assert "sensib" in prompt or "vertraulich" in prompt or "daten" in prompt

    def test_all_playbooks_have_required_fields(self):
        """Test dass alle Playbooks Pflichtfelder haben."""
        playbooks = self.service.list_playbooks(status=None)
        for playbook in playbooks:
            assert playbook.id is not None
            assert len(playbook.id) > 0
            assert playbook.name is not None
            assert len(playbook.name) > 0
            assert playbook.system_prompt is not None
            assert len(playbook.system_prompt) > 0
            assert playbook.prompt_version is not None

    def test_playbooks_have_tool_policy(self):
        """Test dass Playbooks Tool Policy haben."""
        playbooks = self.service.list_playbooks()
        for playbook in playbooks:
            assert hasattr(playbook, "tool_policy")
            # no_pii_in_output sollte standardmäßig true sein
            assert playbook.tool_policy.get("no_pii_in_output") is True


class TestGetPlaybookServiceSingleton:
    """Tests für Singleton Pattern."""

    def test_singleton_returns_same_instance(self):
        """Test dass get_playbook_service Singleton zurückgibt."""
        service1 = get_playbook_service()
        service2 = get_playbook_service()
        assert service1 is service2
