"""
Unit tests for notification URL routing.
"""
from unittest.mock import Mock, patch
import pytest


class TestNotificationURLRouting:
    """Test URL routing for notification endpoints."""

    def test_router_registered_with_empty_prefix(self):
        """Test that router is registered with empty prefix."""
        from smoothschedule.communication.notifications.urls import router

        # Assert
        assert router is not None
        # The router should have NotificationViewSet registered
        assert len(router.registry) > 0

    def test_notification_viewset_basename(self):
        """Test that NotificationViewSet has correct basename."""
        from smoothschedule.communication.notifications.urls import router

        # Find the registration for NotificationViewSet
        registrations = [r for r in router.registry if r[2] == 'notification']

        # Assert
        assert len(registrations) == 1
        assert registrations[0][2] == 'notification'

    def test_list_endpoint_url_pattern(self):
        """Test that list endpoint URL is correct."""
        # The list endpoint should be at the root: /api/notifications/
        # This is handled by the router with empty prefix

        # Arrange
        expected_url = ''  # Empty prefix in urls.py

        # Assert
        assert expected_url == ''

    def test_detail_endpoint_url_pattern(self):
        """Test that detail endpoint URL pattern is correct."""
        # Detail endpoints should be: /api/notifications/{pk}/

        # Arrange
        notification_id = 123
        expected_pattern = f'{notification_id}/'

        # Assert
        assert expected_pattern == f'{notification_id}/'

    def test_unread_count_action_url(self):
        """Test unread_count action URL pattern."""
        # Should be: /api/notifications/unread_count/

        # Arrange
        expected_url = 'unread_count/'

        # Assert
        assert expected_url == 'unread_count/'

    def test_mark_read_action_url(self):
        """Test mark_read action URL pattern."""
        # Should be: /api/notifications/{pk}/mark_read/

        # Arrange
        notification_id = 42
        expected_url = f'{notification_id}/mark_read/'

        # Assert
        assert expected_url == f'{notification_id}/mark_read/'

    def test_mark_all_read_action_url(self):
        """Test mark_all_read action URL pattern."""
        # Should be: /api/notifications/mark_all_read/

        # Arrange
        expected_url = 'mark_all_read/'

        # Assert
        assert expected_url == 'mark_all_read/'

    def test_clear_all_action_url(self):
        """Test clear_all action URL pattern."""
        # Should be: /api/notifications/clear_all/

        # Arrange
        expected_url = 'clear_all/'

        # Assert
        assert expected_url == 'clear_all/'


class TestNotificationURLConfiguration:
    """Test URL configuration and patterns."""

    def test_urlpatterns_includes_router_urls(self):
        """Test that urlpatterns includes router URLs."""
        from smoothschedule.communication.notifications import urls

        # Assert
        assert hasattr(urls, 'urlpatterns')
        assert urls.urlpatterns is not None
        assert len(urls.urlpatterns) > 0

    def test_router_is_default_router(self):
        """Test that DefaultRouter is used."""
        from smoothschedule.communication.notifications.urls import router
        from rest_framework.routers import DefaultRouter

        # Assert
        assert isinstance(router, DefaultRouter)

    def test_notification_viewset_registration(self):
        """Test that NotificationViewSet is properly registered."""
        from smoothschedule.communication.notifications.urls import router
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Find the viewset in registry
        viewsets = [r[1] for r in router.registry]

        # Assert
        assert NotificationViewSet in viewsets


class TestNotificationHTTPMethods:
    """Test HTTP methods supported by notification endpoints."""

    def test_list_supports_get(self):
        """Test that list endpoint supports GET."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # NotificationViewSet inherits from ModelViewSet
        # which supports GET for list by default
        assert hasattr(NotificationViewSet, 'list')

    def test_unread_count_supports_get(self):
        """Test that unread_count action supports GET."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action method
        method = getattr(NotificationViewSet, 'unread_count')

        # Assert - should have mapping that includes 'get'
        assert hasattr(method, 'mapping')
        assert 'get' in method.mapping

    def test_mark_read_supports_post(self):
        """Test that mark_read action supports POST."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action method
        method = getattr(NotificationViewSet, 'mark_read')

        # Assert
        assert hasattr(method, 'mapping')
        assert 'post' in method.mapping

    def test_mark_all_read_supports_post(self):
        """Test that mark_all_read action supports POST."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action method
        method = getattr(NotificationViewSet, 'mark_all_read')

        # Assert
        assert hasattr(method, 'mapping')
        assert 'post' in method.mapping

    def test_clear_all_supports_delete(self):
        """Test that clear_all action supports DELETE."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action method
        method = getattr(NotificationViewSet, 'clear_all')

        # Assert
        assert hasattr(method, 'mapping')
        assert 'delete' in method.mapping

    def test_detail_supports_get(self):
        """Test that detail endpoint supports GET."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # ModelViewSet provides retrieve by default
        assert hasattr(NotificationViewSet, 'retrieve')

    def test_create_not_implemented(self):
        """Test that manual notification creation via API might be restricted."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # NotificationViewSet inherits from ModelViewSet
        # which includes create, but notifications are typically created
        # via signals, not direct API calls
        assert hasattr(NotificationViewSet, 'create')


class TestActionDetailConfiguration:
    """Test action detail configuration (detail vs list actions)."""

    def test_unread_count_is_list_action(self):
        """Test that unread_count is a list action (detail=False)."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action
        method = getattr(NotificationViewSet, 'unread_count')

        # Assert - detail should be False
        assert hasattr(method, 'detail')
        assert method.detail is False

    def test_mark_read_is_detail_action(self):
        """Test that mark_read is a detail action (detail=True)."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action
        method = getattr(NotificationViewSet, 'mark_read')

        # Assert - detail should be True
        assert hasattr(method, 'detail')
        assert method.detail is True

    def test_mark_all_read_is_list_action(self):
        """Test that mark_all_read is a list action (detail=False)."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action
        method = getattr(NotificationViewSet, 'mark_all_read')

        # Assert - detail should be False
        assert hasattr(method, 'detail')
        assert method.detail is False

    def test_clear_all_is_list_action(self):
        """Test that clear_all is a list action (detail=False)."""
        from smoothschedule.communication.notifications.views import NotificationViewSet

        # Get the action
        method = getattr(NotificationViewSet, 'clear_all')

        # Assert - detail should be False
        assert hasattr(method, 'detail')
        assert method.detail is False


class TestURLReversal:
    """Test URL reversal for notification endpoints."""

    def test_list_url_name(self):
        """Test that list URL has correct name."""
        # With basename 'notification', list should be 'notification-list'
        expected_name = 'notification-list'

        # Assert
        assert expected_name == 'notification-list'

    def test_detail_url_name(self):
        """Test that detail URL has correct name."""
        # With basename 'notification', detail should be 'notification-detail'
        expected_name = 'notification-detail'

        # Assert
        assert expected_name == 'notification-detail'

    def test_unread_count_url_name(self):
        """Test that unread_count URL has correct name."""
        # Custom action with basename 'notification' -> 'notification-unread-count'
        expected_name = 'notification-unread-count'

        # Assert
        assert expected_name == 'notification-unread-count'

    def test_mark_read_url_name(self):
        """Test that mark_read URL has correct name."""
        # Detail action with basename 'notification' -> 'notification-mark-read'
        expected_name = 'notification-mark-read'

        # Assert
        assert expected_name == 'notification-mark-read'

    def test_mark_all_read_url_name(self):
        """Test that mark_all_read URL has correct name."""
        expected_name = 'notification-mark-all-read'

        # Assert
        assert expected_name == 'notification-mark-all-read'

    def test_clear_all_url_name(self):
        """Test that clear_all URL has correct name."""
        expected_name = 'notification-clear-all'

        # Assert
        assert expected_name == 'notification-clear-all'


class TestRouterConfiguration:
    """Test router configuration details."""

    def test_router_trailing_slash_default(self):
        """Test that router uses default trailing slash behavior."""
        from smoothschedule.communication.notifications.urls import router

        # DefaultRouter has trailing slash by default
        # This is configurable but default is True
        assert router is not None

    def test_router_generates_root_view(self):
        """Test that DefaultRouter generates root view."""
        from smoothschedule.communication.notifications.urls import router
        from rest_framework.routers import DefaultRouter

        # DefaultRouter includes a root view showing all endpoints
        assert isinstance(router, DefaultRouter)

    def test_empty_prefix_in_registration(self):
        """Test that viewset is registered with empty prefix."""
        from smoothschedule.communication.notifications.urls import router

        # Find the NotificationViewSet registration
        registrations = [r for r in router.registry if r[2] == 'notification']

        # Assert - prefix should be empty string
        assert len(registrations) == 1
        assert registrations[0][0] == ''


class TestURLQueryParameters:
    """Test URL query parameter handling."""

    def test_list_read_filter_parameter(self):
        """Test that list endpoint accepts read query parameter."""
        # The view accepts ?read=true or ?read=false
        # This is tested in the view, but we verify the pattern here

        # Arrange
        valid_values = ['true', 'false', 'True', 'False']

        # Assert
        for value in valid_values:
            param = f'read={value}'
            assert 'read=' in param

    def test_list_limit_parameter(self):
        """Test that list endpoint accepts limit query parameter."""
        # The view accepts ?limit=N

        # Arrange
        param = 'limit=20'

        # Assert
        assert 'limit=' in param

    def test_multiple_query_parameters(self):
        """Test URL with multiple query parameters."""
        # Should support ?read=false&limit=10

        # Arrange
        url_params = 'read=false&limit=10'

        # Assert
        assert 'read=' in url_params
        assert 'limit=' in url_params
        assert '&' in url_params
