"""
Tests for core admin base classes and mixins.

These tests verify the functionality of the base admin classes and mixins
that provide standardized behavior across all admin interfaces.
"""

from django.contrib.admin.sites import AdminSite
from django.contrib.auth import get_user_model
from django.test import RequestFactory, TestCase

from apps.core.admin.base import BaseModelAdmin
from apps.core.admin.mixins import (
    BulkStatusChangeMixin,
    ExportActionMixin,
    QueryOptimizationMixin,
    ReadOnlyAdminMixin,
    SlugFieldMixin,
    TimestampFieldsMixin,
)

User = get_user_model()


class TestBaseModelAdmin(TestCase):
    """Tests for BaseModelAdmin class."""

    def test_default_settings(self):
        """Verify default settings are correctly set."""
        admin = BaseModelAdmin(model=User, admin_site=AdminSite())

        assert admin.list_per_page == 50
        assert admin.show_full_result_count is False
        assert admin.empty_value_display == "-"
        assert admin.save_on_top is True
        assert admin.preserve_filters is True


class TestQueryOptimizationMixin(TestCase):
    """Tests for QueryOptimizationMixin."""

    def test_queryset_optimization(self):
        """Verify select_related and prefetch_related are applied."""

        class TestAdmin(QueryOptimizationMixin, BaseModelAdmin):
            list_select_related = ["profile"]
            list_prefetch_related = ["groups"]

        admin = TestAdmin(model=User, admin_site=AdminSite())
        factory = RequestFactory()
        request = factory.get("/admin/")
        request.user = User(is_superuser=True)

        qs = admin.get_queryset(request)
        # The queryset should have the select_related/prefetch_related applied
        assert qs is not None


class TestReadOnlyAdminMixin(TestCase):
    """Tests for ReadOnlyAdminMixin."""

    def setUp(self):
        self.factory = RequestFactory()
        self.site = AdminSite()

    def test_has_add_permission_returns_false(self):
        """Verify add permission is disabled."""

        class TestAdmin(ReadOnlyAdminMixin, BaseModelAdmin):
            pass

        admin = TestAdmin(model=User, admin_site=self.site)
        request = self.factory.get("/admin/")
        request.user = User(is_superuser=True)

        assert admin.has_add_permission(request) is False

    def test_has_change_permission_returns_false(self):
        """Verify change permission is disabled."""

        class TestAdmin(ReadOnlyAdminMixin, BaseModelAdmin):
            pass

        admin = TestAdmin(model=User, admin_site=self.site)
        request = self.factory.get("/admin/")
        request.user = User(is_superuser=False)

        assert admin.has_change_permission(request) is False

    def test_has_delete_permission_superuser_only(self):
        """Verify delete permission is superuser only."""

        class TestAdmin(ReadOnlyAdminMixin, BaseModelAdmin):
            pass

        admin = TestAdmin(model=User, admin_site=self.site)
        request = self.factory.get("/admin/")

        # Non-superuser
        request.user = User(is_superuser=False)
        assert admin.has_delete_permission(request) is False

        # Superuser
        request.user = User(is_superuser=True)
        assert admin.has_delete_permission(request) is True


class TestTimestampFieldsMixin(TestCase):
    """Tests for TimestampFieldsMixin."""

    def test_timestamp_fieldset(self):
        """Verify timestamp fieldset is correctly generated."""
        fieldset = TimestampFieldsMixin.get_timestamp_fieldset()

        assert len(fieldset) == 1
        assert fieldset[0][0] == "Metadata"
        assert "collapse" in fieldset[0][1]["classes"]
        assert fieldset[0][1]["fields"] == ("created_at", "updated_at")


class TestSlugFieldMixin(TestCase):
    """Tests for SlugFieldMixin."""

    def test_default_slug_source_field(self):
        """Verify default slug source field is 'name'."""

        class TestAdmin(SlugFieldMixin, BaseModelAdmin):
            pass

        admin = TestAdmin(model=User, admin_site=AdminSite())
        assert admin.slug_source_field == "name"


class TestExportActionMixin(TestCase):
    """Tests for ExportActionMixin."""

    def setUp(self):
        self.factory = RequestFactory()
        self.site = AdminSite()

    def test_get_export_filename(self):
        """Verify export filename generation."""

        class TestAdmin(ExportActionMixin, BaseModelAdmin):
            export_filename_prefix = "test_export"

        admin = TestAdmin(model=User, admin_site=self.site)

        csv_filename = admin.get_export_filename("csv")
        assert csv_filename.startswith("test_export_")
        assert csv_filename.endswith(".csv")

        json_filename = admin.get_export_filename("json")
        assert json_filename.startswith("test_export_")
        assert json_filename.endswith(".json")

    def test_export_actions_registered(self):
        """Verify export actions are registered."""

        class TestAdmin(ExportActionMixin, BaseModelAdmin):
            pass

        admin = TestAdmin(model=User, admin_site=self.site)
        request = self.factory.get("/admin/")
        request.user = User(is_superuser=True)

        actions = admin.get_actions(request)
        assert "export_to_csv" in actions
        assert "export_to_json" in actions


class TestBulkStatusChangeMixin(TestCase):
    """Tests for BulkStatusChangeMixin."""

    def setUp(self):
        self.factory = RequestFactory()
        self.site = AdminSite()

    def test_bulk_status_actions_generated(self):
        """Verify bulk status actions are generated from status_choices."""

        class TestAdmin(BulkStatusChangeMixin, BaseModelAdmin):
            status_field = "status"
            status_choices = [
                ("active", "Activate"),
                ("inactive", "Deactivate"),
            ]

        admin = TestAdmin(model=User, admin_site=self.site)
        actions = admin.get_bulk_status_actions()

        assert "set_status_active" in actions
        assert "set_status_inactive" in actions
