"""
Tests fuer die Jitsi API.

Testet:
- Meeting-Raum generieren
- Einzel-Einladung senden
- Bulk-Einladungen senden
"""

import pytest
from unittest.mock import patch, MagicMock

from jitsi_api import (
    generate_room_name,
    build_jitsi_url,
    JitsiInvitation,
    JitsiBulkInvitation
)


class TestHelperFunctions:
    """Tests fuer Helper-Funktionen."""

    def test_generate_room_name_format(self):
        """Test: Raumname hat korrektes Format."""
        room_name = generate_room_name()

        assert room_name.startswith("BreakPilot-")
        assert len(room_name) == len("BreakPilot-") + 12  # 12 hex chars

    def test_generate_room_name_unique(self):
        """Test: Raumnamen sind eindeutig."""
        names = [generate_room_name() for _ in range(100)]
        unique_names = set(names)

        assert len(unique_names) == 100

    def test_build_jitsi_url_default_server(self):
        """Test: URL mit Standard-Server."""
        url = build_jitsi_url("TestRoom123")

        assert url == "https://meet.jit.si/TestRoom123"

    def test_build_jitsi_url_with_special_chars(self):
        """Test: URL mit Sonderzeichen im Raumnamen."""
        url = build_jitsi_url("BreakPilot-abc123def456")

        assert "BreakPilot-abc123def456" in url


class TestJitsiInvitationModel:
    """Tests fuer das JitsiInvitation Model."""

    def test_valid_invitation(self):
        """Test: Gueltiges Einladungsmodell."""
        invitation = JitsiInvitation(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            meeting_title="Elterngespraech",
            meeting_date="20. Dezember 2024",
            meeting_time="14:00 Uhr"
        )

        assert invitation.to_email == "parent@example.com"
        assert invitation.to_name == "Max Mustermann"
        assert invitation.organizer_name == "BreakPilot Lehrer"  # Default
        assert invitation.room_name is None  # Optional

    def test_invitation_with_room_name(self):
        """Test: Einladung mit vordefiniertem Raumname."""
        invitation = JitsiInvitation(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            meeting_title="Elterngespraech",
            meeting_date="20. Dezember 2024",
            meeting_time="14:00 Uhr",
            room_name="CustomRoom123"
        )

        assert invitation.room_name == "CustomRoom123"

    def test_invitation_with_additional_info(self):
        """Test: Einladung mit zusaetzlichen Informationen."""
        invitation = JitsiInvitation(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            meeting_title="Elterngespraech",
            meeting_date="20. Dezember 2024",
            meeting_time="14:00 Uhr",
            additional_info="Bitte Zeugnisse mitbringen."
        )

        assert invitation.additional_info == "Bitte Zeugnisse mitbringen."


class TestJitsiBulkInvitationModel:
    """Tests fuer das JitsiBulkInvitation Model."""

    def test_valid_bulk_invitation(self):
        """Test: Gueltiges Bulk-Einladungsmodell."""
        bulk = JitsiBulkInvitation(
            recipients=[
                {"email": "parent1@example.com", "name": "Eltern A"},
                {"email": "parent2@example.com", "name": "Eltern B"}
            ],
            meeting_title="Elternabend",
            meeting_date="20. Dezember 2024",
            meeting_time="19:00 Uhr"
        )

        assert len(bulk.recipients) == 2
        assert bulk.meeting_title == "Elternabend"
        assert bulk.organizer_name == "BreakPilot Lehrer"


class TestJitsiAPIIntegration:
    """Integration Tests fuer die Jitsi API."""

    BASE_URL = "http://localhost:8000"

    def test_generate_room_endpoint(self):
        """Test: Room-Generator Endpoint."""
        import requests

        try:
            response = requests.get(f"{self.BASE_URL}/api/jitsi/room", timeout=5)

            if response.status_code == 200:
                data = response.json()
                assert "room_name" in data
                assert "jitsi_url" in data
                assert data["room_name"].startswith("BreakPilot-")
        except requests.exceptions.ConnectionError:
            pytest.skip("Backend nicht erreichbar")

    def test_send_invitation_endpoint(self):
        """Test: Einladungs-Endpoint (Integrationstest mit echtem Email-Service)."""
        import requests

        try:
            response = requests.post(
                f"{self.BASE_URL}/api/jitsi/invite",
                json={
                    "to_email": "parent@example.com",
                    "to_name": "Max Mustermann",
                    "meeting_title": "Test Meeting",
                    "meeting_date": "20. Dezember 2024",
                    "meeting_time": "14:00 Uhr"
                },
                timeout=5
            )

            if response.status_code == 200:
                data = response.json()
                assert "jitsi_url" in data
                assert "room_name" in data
                assert "email_sent" in data
                assert data["room_name"].startswith("BreakPilot-")
        except requests.exceptions.ConnectionError:
            pytest.skip("Backend nicht erreichbar")

    def test_bulk_invitation_endpoint(self):
        """Test: Bulk-Einladungs-Endpoint (Integrationstest)."""
        import requests

        try:
            response = requests.post(
                f"{self.BASE_URL}/api/jitsi/invite/bulk",
                json={
                    "recipients": [
                        {"email": "parent1@example.com", "name": "Eltern A"},
                        {"email": "parent2@example.com", "name": "Eltern B"}
                    ],
                    "meeting_title": "Elternabend",
                    "meeting_date": "20. Dezember 2024",
                    "meeting_time": "19:00 Uhr"
                },
                timeout=5
            )

            if response.status_code == 200:
                data = response.json()
                assert "jitsi_url" in data
                assert "sent" in data
                assert "failed" in data
                assert data["sent"] == 2  # Beide Emails sollten gesendet werden
        except requests.exceptions.ConnectionError:
            pytest.skip("Backend nicht erreichbar")
