"""
Tests for Themis middleware: TimezoneMiddleware and ThemeMiddleware.
"""
from unittest.mock import MagicMock

from django.contrib.auth import get_user_model
from django.test import RequestFactory, TestCase
from django.utils import timezone

from themis.middleware import ThemeMiddleware, TimezoneMiddleware

User = get_user_model()


class TimezoneMiddlewareTest(TestCase):
    """Tests for TimezoneMiddleware."""

    def setUp(self):
        self.factory = RequestFactory()
        self.get_response = MagicMock(return_value=MagicMock())
        self.middleware = TimezoneMiddleware(self.get_response)

    def test_authenticated_user_timezone_activated(self):
        """Authenticated user's timezone is activated during request."""
        user = User.objects.create_user(username="tzuser", password="pass123")
        user.profile.home_timezone = "America/Toronto"
        user.profile.save()

        request = self.factory.get("/")
        request.user = user

        # Capture the timezone during the request
        activated_tz = []

        def capture_response(req):
            activated_tz.append(str(timezone.get_current_timezone()))
            return MagicMock()

        self.middleware.get_response = capture_response
        self.middleware(request)

        self.assertEqual(activated_tz[0], "America/Toronto")

    def test_traveling_user_uses_current_timezone(self):
        """Traveling user's current_timezone is used."""
        user = User.objects.create_user(username="traveler", password="pass123")
        user.profile.home_timezone = "America/Toronto"
        user.profile.current_timezone = "Asia/Tokyo"
        user.profile.save()

        request = self.factory.get("/")
        request.user = user

        activated_tz = []

        def capture_response(req):
            activated_tz.append(str(timezone.get_current_timezone()))
            return MagicMock()

        self.middleware.get_response = capture_response
        self.middleware(request)

        self.assertEqual(activated_tz[0], "Asia/Tokyo")

    def test_anonymous_user_gets_utc(self):
        """Anonymous users get UTC timezone."""
        from django.contrib.auth.models import AnonymousUser

        request = self.factory.get("/")
        request.user = AnonymousUser()

        activated_tz = []

        def capture_response(req):
            activated_tz.append(str(timezone.get_current_timezone()))
            return MagicMock()

        self.middleware.get_response = capture_response
        self.middleware(request)

        self.assertEqual(activated_tz[0], "UTC")

    def test_timezone_deactivated_after_response(self):
        """Timezone is deactivated after the response is generated."""
        user = User.objects.create_user(username="deactuser", password="pass123")
        user.profile.home_timezone = "Europe/London"
        user.profile.save()

        request = self.factory.get("/")
        request.user = user
        self.middleware(request)

        # After middleware completes, timezone is deactivated.
        # Django falls back to settings.TIME_ZONE.
        from django.conf import settings

        expected_tz = getattr(settings, "TIME_ZONE", "UTC")
        current = str(timezone.get_current_timezone())
        self.assertEqual(current, expected_tz)


class ThemeMiddlewareTest(TestCase):
    """Tests for ThemeMiddleware."""

    def setUp(self):
        self.factory = RequestFactory()
        self.get_response = MagicMock(return_value=MagicMock())
        self.middleware = ThemeMiddleware(self.get_response)

    def test_authenticated_user_theme_attached(self):
        """Authenticated user's theme settings are attached to request."""
        user = User.objects.create_user(username="themeuser", password="pass123")
        user.profile.theme_mode = "dark"
        user.profile.theme_name = "dracula"
        user.profile.dark_theme_name = "night"
        user.profile.save()

        request = self.factory.get("/")
        request.user = user
        self.middleware(request)

        self.assertEqual(request.themis_theme_mode, "dark")
        self.assertEqual(request.themis_theme_name, "dracula")
        self.assertEqual(request.themis_dark_theme_name, "night")

    def test_anonymous_user_gets_defaults(self):
        """Anonymous users get default theme settings."""
        from django.contrib.auth.models import AnonymousUser

        request = self.factory.get("/")
        request.user = AnonymousUser()
        self.middleware(request)

        self.assertEqual(request.themis_theme_mode, "auto")
        self.assertEqual(request.themis_theme_name, "corporate")
        self.assertEqual(request.themis_dark_theme_name, "business")

    def test_user_without_profile_gets_defaults(self):
        """User without profile attribute gets default theme settings."""
        request = self.factory.get("/")
        request.user = MagicMock(is_authenticated=True, spec=[])
        # spec=[] means no 'profile' attribute
        self.middleware(request)

        self.assertEqual(request.themis_theme_mode, "auto")
        self.assertEqual(request.themis_theme_name, "corporate")
        self.assertEqual(request.themis_dark_theme_name, "business")
