"""
Tests fuer den Email-Service.

Testet:
- EmailService Klasse
- SMTP Verbindung (mit Mock)
- Messenger-Benachrichtigungen
- Jitsi-Einladungen
"""

import pytest
from unittest.mock import patch, MagicMock

from email_service import EmailService, EmailResult


class TestEmailService:
    """Tests fuer die EmailService Klasse."""

    def test_init_default_values(self):
        """Test: Service wird mit Default-Werten initialisiert."""
        service = EmailService()

        # Default ist 'mailpit' in Docker, 'localhost' lokal - beides akzeptieren
        assert service.host in ("localhost", "mailpit")
        assert service.port == 1025
        # from_name kann "BreakPilot" oder "BreakPilot Dev" sein (dev environment)
        assert service.from_name in ("BreakPilot", "BreakPilot Dev")
        assert service.from_addr == "noreply@breakpilot.app"

    def test_init_custom_values(self):
        """Test: Service wird mit benutzerdefinierten Werten initialisiert."""
        service = EmailService(
            host="smtp.example.com",
            port=587,
            username="user",
            password="pass",
            from_name="Custom",
            from_addr="custom@example.com",
            use_tls=True
        )

        assert service.host == "smtp.example.com"
        assert service.port == 587
        assert service.username == "user"
        assert service.password == "pass"
        assert service.from_name == "Custom"
        assert service.from_addr == "custom@example.com"
        assert service.use_tls is True

    @patch('email_service.smtplib.SMTP')
    def test_send_email_success(self, mock_smtp):
        """Test: Email wird erfolgreich gesendet."""
        mock_instance = MagicMock()
        mock_smtp.return_value.__enter__ = MagicMock(return_value=mock_instance)
        mock_smtp.return_value.__exit__ = MagicMock(return_value=False)

        service = EmailService()
        result = service.send_email(
            to_email="test@example.com",
            subject="Test",
            body_text="Test Body"
        )

        assert result.success is True
        assert result.recipient == "test@example.com"
        assert result.sent_at is not None

    @patch('email_service.smtplib.SMTP')
    def test_send_email_with_html(self, mock_smtp):
        """Test: Email mit HTML wird gesendet."""
        mock_instance = MagicMock()
        mock_smtp.return_value.__enter__ = MagicMock(return_value=mock_instance)
        mock_smtp.return_value.__exit__ = MagicMock(return_value=False)

        service = EmailService()
        result = service.send_email(
            to_email="test@example.com",
            subject="Test",
            body_text="Plain text",
            body_html="<h1>HTML</h1>"
        )

        assert result.success is True

    @patch('email_service.smtplib.SMTP')
    def test_send_email_failure(self, mock_smtp):
        """Test: Fehler beim Email-Versand wird behandelt."""
        import smtplib
        mock_smtp.side_effect = smtplib.SMTPException("Connection failed")

        service = EmailService()
        result = service.send_email(
            to_email="test@example.com",
            subject="Test",
            body_text="Test Body"
        )

        assert result.success is False
        assert result.error is not None
        assert "SMTP" in result.error

    @patch('email_service.smtplib.SMTP')
    def test_send_messenger_notification(self, mock_smtp):
        """Test: Messenger-Benachrichtigung wird gesendet."""
        mock_instance = MagicMock()
        mock_smtp.return_value.__enter__ = MagicMock(return_value=mock_instance)
        mock_smtp.return_value.__exit__ = MagicMock(return_value=False)

        service = EmailService()
        result = service.send_messenger_notification(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            sender_name="Frau Lehrerin",
            message_content="Bitte bringen Sie morgen das Buch mit."
        )

        assert result.success is True
        assert result.recipient == "parent@example.com"

    @patch('email_service.smtplib.SMTP')
    def test_send_jitsi_invitation(self, mock_smtp):
        """Test: Jitsi-Einladung wird gesendet."""
        mock_instance = MagicMock()
        mock_smtp.return_value.__enter__ = MagicMock(return_value=mock_instance)
        mock_smtp.return_value.__exit__ = MagicMock(return_value=False)

        service = EmailService()
        result = service.send_jitsi_invitation(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            organizer_name="Frau Lehrerin",
            meeting_title="Elterngespraech",
            meeting_date="20. Dezember 2024",
            meeting_time="14:00 Uhr",
            jitsi_url="https://meet.jit.si/BreakPilot-test123"
        )

        assert result.success is True
        assert result.recipient == "parent@example.com"

    @patch('email_service.smtplib.SMTP')
    def test_send_jitsi_invitation_with_additional_info(self, mock_smtp):
        """Test: Jitsi-Einladung mit zusaetzlichen Infos wird gesendet."""
        mock_instance = MagicMock()
        mock_smtp.return_value.__enter__ = MagicMock(return_value=mock_instance)
        mock_smtp.return_value.__exit__ = MagicMock(return_value=False)

        service = EmailService()
        result = service.send_jitsi_invitation(
            to_email="parent@example.com",
            to_name="Max Mustermann",
            organizer_name="Frau Lehrerin",
            meeting_title="Elterngespraech",
            meeting_date="20. Dezember 2024",
            meeting_time="14:00 Uhr",
            jitsi_url="https://meet.jit.si/BreakPilot-test123",
            additional_info="Bitte bereiten Sie die Zeugnismappe vor."
        )

        assert result.success is True


class TestEmailResult:
    """Tests fuer das EmailResult Dataclass."""

    def test_success_result(self):
        """Test: Erfolgreiche Email-Antwort."""
        result = EmailResult(
            success=True,
            message_id="msg-123",
            recipient="test@example.com",
            sent_at="2024-12-18T10:00:00"
        )

        assert result.success is True
        assert result.message_id == "msg-123"
        assert result.error is None

    def test_failure_result(self):
        """Test: Fehlgeschlagene Email-Antwort."""
        result = EmailResult(
            success=False,
            error="Connection refused",
            recipient="test@example.com"
        )

        assert result.success is False
        assert result.error == "Connection refused"
        assert result.sent_at is None
