"""
Root pytest configuration for ThrillWiki backend tests.

This file contains shared fixtures and configuration used across
all test modules (unit, integration, e2e).
"""

import os

import django
import pytest

# Configure Django settings before any tests run
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.django.test")
django.setup()


# =============================================================================
# Database Fixtures
# =============================================================================

# Note: pytest-django uses the DATABASES setting from the test settings module
# (config.django.test). Do NOT override DATABASES to SQLite here as it breaks
# GeoDjango models that require PostGIS (or properly configured SpatiaLite).


@pytest.fixture
def db_session(db):
    """Provide database access with automatic cleanup."""
    yield db


# =============================================================================
# User Fixtures
# =============================================================================


@pytest.fixture
def user(db):
    """Create a regular test user."""
    from tests.factories import UserFactory

    return UserFactory()


@pytest.fixture
def staff_user(db):
    """Create a staff test user."""
    from tests.factories import StaffUserFactory

    return StaffUserFactory()


@pytest.fixture
def superuser(db):
    """Create a superuser test user."""
    from tests.factories import SuperUserFactory

    return SuperUserFactory()


@pytest.fixture
def moderator_user(db):
    """Create a moderator test user."""
    from tests.factories import StaffUserFactory

    user = StaffUserFactory(username="moderator")
    return user


# =============================================================================
# API Client Fixtures
# =============================================================================


@pytest.fixture
def api_client():
    """Create an unauthenticated API client."""
    from rest_framework.test import APIClient

    return APIClient()


@pytest.fixture
def authenticated_api_client(api_client, user):
    """Create an authenticated API client."""
    api_client.force_authenticate(user=user)
    return api_client


@pytest.fixture
def staff_api_client(api_client, staff_user):
    """Create an API client authenticated as staff."""
    api_client.force_authenticate(user=staff_user)
    return api_client


@pytest.fixture
def superuser_api_client(api_client, superuser):
    """Create an API client authenticated as superuser."""
    api_client.force_authenticate(user=superuser)
    return api_client


# =============================================================================
# Model Fixtures
# =============================================================================


@pytest.fixture
def park(db):
    """Create a test park."""
    from tests.factories import ParkFactory

    return ParkFactory()


@pytest.fixture
def operating_park(db):
    """Create an operating test park."""
    from tests.factories import ParkFactory

    return ParkFactory(status="OPERATING")


@pytest.fixture
def ride(db, park):
    """Create a test ride."""
    from tests.factories import RideFactory

    return RideFactory(park=park)


@pytest.fixture
def operating_ride(db, operating_park):
    """Create an operating test ride."""
    from tests.factories import RideFactory

    return RideFactory(park=operating_park, status="OPERATING")


@pytest.fixture
def park_photo(db, park, user):
    """Create a test park photo."""
    from tests.factories import ParkPhotoFactory

    return ParkPhotoFactory(park=park, uploaded_by=user)


@pytest.fixture
def ride_photo(db, ride, user):
    """Create a test ride photo."""
    from tests.factories import RidePhotoFactory

    return RidePhotoFactory(ride=ride, uploaded_by=user)


@pytest.fixture
def company(db):
    """Create a test company."""
    from tests.factories import CompanyFactory

    return CompanyFactory()


@pytest.fixture
def park_area(db, park):
    """Create a test park area."""
    from tests.factories import ParkAreaFactory

    return ParkAreaFactory(park=park)


# =============================================================================
# Request Fixtures
# =============================================================================


@pytest.fixture
def request_factory():
    """Create a Django request factory."""
    from django.test import RequestFactory

    return RequestFactory()


@pytest.fixture
def rf():
    """Alias for request_factory (common pytest-django convention)."""
    from django.test import RequestFactory

    return RequestFactory()


# =============================================================================
# Utility Fixtures
# =============================================================================


@pytest.fixture
def mock_cloudflare_image():
    """Create a mock Cloudflare image."""
    from tests.factories import CloudflareImageFactory

    return CloudflareImageFactory()


@pytest.fixture
def temp_image():
    """Create a temporary image file for upload testing."""
    from io import BytesIO

    from django.core.files.uploadedfile import SimpleUploadedFile
    from PIL import Image

    # Create a simple test image
    image = Image.new("RGB", (100, 100), color="red")
    image_io = BytesIO()
    image.save(image_io, format="JPEG")
    image_io.seek(0)

    return SimpleUploadedFile(
        name="test_image.jpg",
        content=image_io.read(),
        content_type="image/jpeg",
    )


@pytest.fixture(autouse=True)
def enable_db_access_for_all_tests(db):
    """
    Enable database access for all tests by default.

    This is useful for integration tests that need database access
    without explicitly requesting the 'db' fixture.
    """
    pass


# =============================================================================
# Cleanup Fixtures
# =============================================================================


@pytest.fixture(autouse=True)
def clear_cache():
    """Clear Django cache before each test."""
    from django.core.cache import cache

    cache.clear()
    yield
    cache.clear()


# =============================================================================
# Marker Registration
# =============================================================================


def pytest_configure(config):
    """Register custom pytest markers."""
    config.addinivalue_line("markers", "unit: Unit tests (fast, isolated)")
    config.addinivalue_line("markers", "integration: Integration tests (may use database)")
    config.addinivalue_line("markers", "e2e: End-to-end browser tests (slow, requires server)")
    config.addinivalue_line("markers", "slow: Tests that take a long time to run")
    config.addinivalue_line("markers", "api: API endpoint tests")
