"""
Tests for notifications/queue_helpers.py

Tests cover:
- send_queue_notification function
- send_queue_failed_notification function
- send_queue_failed_notification_from_session function
- send_research_completed_notification_from_session function
- send_research_failed_notification_from_session function
"""

from unittest.mock import Mock, patch


class TestSendQueueNotification:
    """Tests for send_queue_notification function."""

    @patch(
        "local_deep_research.notifications.queue_helpers.NotificationManager"
    )
    def test_sends_notification_with_context(self, mock_manager_class):
        """Test that notification is sent with correct context."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_notification,
        )
        from local_deep_research.notifications.templates import EventType

        mock_manager = Mock()
        mock_manager.send_notification.return_value = True
        mock_manager_class.return_value = mock_manager

        result = send_queue_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            settings_snapshot={"key": "value"},
            position=5,
        )

        assert result is True
        mock_manager.send_notification.assert_called_once()
        call_args = mock_manager.send_notification.call_args
        assert call_args.kwargs["event_type"] == EventType.RESEARCH_QUEUED
        context = call_args.kwargs["context"]
        assert context["query"] == "Test query"
        assert context["research_id"] == "research-123"
        assert context["position"] == 5

    @patch(
        "local_deep_research.notifications.queue_helpers.NotificationManager"
    )
    def test_sends_notification_without_position(self, mock_manager_class):
        """Test notification without position parameter."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_notification,
        )

        mock_manager = Mock()
        mock_manager.send_notification.return_value = True
        mock_manager_class.return_value = mock_manager

        result = send_queue_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            settings_snapshot={},
        )

        assert result is True
        context = mock_manager.send_notification.call_args.kwargs["context"]
        assert "position" not in context

    @patch(
        "local_deep_research.notifications.queue_helpers.NotificationManager"
    )
    def test_handles_exception(self, mock_manager_class):
        """Test that exceptions are caught and return False."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_notification,
        )

        mock_manager_class.side_effect = RuntimeError("Connection failed")

        result = send_queue_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            settings_snapshot={},
        )

        assert result is False


class TestSendQueueFailedNotification:
    """Tests for send_queue_failed_notification function."""

    @patch(
        "local_deep_research.notifications.queue_helpers.NotificationManager"
    )
    def test_sends_failed_notification(self, mock_manager_class):
        """Test that failed notification is sent."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_failed_notification,
        )
        from local_deep_research.notifications.templates import EventType

        mock_manager = Mock()
        mock_manager.send_notification.return_value = True
        mock_manager_class.return_value = mock_manager

        result = send_queue_failed_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            error_message="Something went wrong",
            settings_snapshot={"key": "value"},
        )

        assert result is True
        call_args = mock_manager.send_notification.call_args
        assert call_args.kwargs["event_type"] == EventType.RESEARCH_FAILED
        context = call_args.kwargs["context"]
        assert context["error"] == "Something went wrong"

    def test_returns_false_without_settings(self):
        """Test that returns False when no settings_snapshot provided."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_failed_notification,
        )

        result = send_queue_failed_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            settings_snapshot=None,
        )

        assert result is False

    @patch(
        "local_deep_research.notifications.queue_helpers.NotificationManager"
    )
    def test_handles_exception(self, mock_manager_class):
        """Test that exceptions return False."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_failed_notification,
        )

        mock_manager_class.side_effect = RuntimeError("Failed")

        result = send_queue_failed_notification(
            username="testuser",
            research_id="research-123",
            query="Test query",
            settings_snapshot={"key": "value"},
        )

        assert result is False


class TestSendQueueFailedNotificationFromSession:
    """Tests for send_queue_failed_notification_from_session function."""

    def test_function_exists(self):
        """Test that the function exists."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_failed_notification_from_session,
        )

        assert callable(send_queue_failed_notification_from_session)

    def test_function_handles_missing_db(self):
        """Test function handles database issues gracefully."""
        from local_deep_research.notifications.queue_helpers import (
            send_queue_failed_notification_from_session,
        )

        # Should not raise with invalid session
        send_queue_failed_notification_from_session(
            username="testuser",
            research_id="research-123",
            query="Test query",
            error_message="Error occurred",
            db_session=None,
        )


class TestSendResearchCompletedNotificationFromSession:
    """Tests for send_research_completed_notification_from_session function."""

    def test_function_exists(self):
        """Test that the function exists."""
        from local_deep_research.notifications.queue_helpers import (
            send_research_completed_notification_from_session,
        )

        assert callable(send_research_completed_notification_from_session)

    def test_function_handles_missing_db(self):
        """Test function handles database issues gracefully."""
        from local_deep_research.notifications.queue_helpers import (
            send_research_completed_notification_from_session,
        )

        # Should not raise with invalid session
        send_research_completed_notification_from_session(
            username="testuser",
            research_id="research-123",
            db_session=None,
        )


class TestSendResearchFailedNotificationFromSession:
    """Tests for send_research_failed_notification_from_session function."""

    def test_function_exists(self):
        """Test that the function exists."""
        from local_deep_research.notifications.queue_helpers import (
            send_research_failed_notification_from_session,
        )

        assert callable(send_research_failed_notification_from_session)

    def test_function_handles_missing_db(self):
        """Test function handles database issues gracefully."""
        from local_deep_research.notifications.queue_helpers import (
            send_research_failed_notification_from_session,
        )

        # Should not raise with invalid session
        send_research_failed_notification_from_session(
            username="testuser",
            research_id="research-123",
            error_message="Error occurred",
            db_session=None,
        )
