"""
Django REST Framework configuration for thrillwiki project.

This module configures DRF, SimpleJWT, dj-rest-auth, CORS, and
drf-spectacular (OpenAPI documentation).

Why python-decouple?
- Already used in base.py for consistency
- Simpler API than django-environ
- Sufficient for our configuration needs
- Better separation of config from code
"""

from datetime import timedelta

from decouple import config

# =============================================================================
# Django REST Framework Settings
# =============================================================================

REST_FRAMEWORK = {
    # Authentication classes (order matters - first match wins)
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework_simplejwt.authentication.JWTAuthentication",
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.TokenAuthentication",  # Backward compatibility
    ],
    # Default permissions - require authentication
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    # Pagination settings
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": config("API_PAGE_SIZE", default=20, cast=int),
    "MAX_PAGE_SIZE": config("API_MAX_PAGE_SIZE", default=100, cast=int),
    # API versioning via Accept header
    "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.AcceptHeaderVersioning",
    "DEFAULT_VERSION": "v1",
    "ALLOWED_VERSIONS": ["v1"],
    # Response rendering
    "DEFAULT_RENDERER_CLASSES": [
        "rest_framework.renderers.JSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    ],
    # Request parsing
    "DEFAULT_PARSER_CLASSES": [
        "rest_framework.parsers.JSONParser",
        "rest_framework.parsers.FormParser",
        "rest_framework.parsers.MultiPartParser",
    ],
    # Custom exception handling
    "EXCEPTION_HANDLER": "apps.core.api.exceptions.custom_exception_handler",
    # Filter backends
    "DEFAULT_FILTER_BACKENDS": [
        "django_filters.rest_framework.DjangoFilterBackend",
        "rest_framework.filters.SearchFilter",
        "rest_framework.filters.OrderingFilter",
    ],
    # Rate limiting
    "DEFAULT_THROTTLE_CLASSES": [
        "rest_framework.throttling.AnonRateThrottle",
        "rest_framework.throttling.UserRateThrottle",
    ],
    "DEFAULT_THROTTLE_RATES": {
        "anon": f"{config('API_RATE_LIMIT_ANON_PER_MINUTE', default=60, cast=int)}/minute",
        "user": f"{config('API_RATE_LIMIT_USER_PER_HOUR', default=1000, cast=int)}/hour",
    },
    # Test settings
    "TEST_REQUEST_DEFAULT_FORMAT": "json",
    "NON_FIELD_ERRORS_KEY": "non_field_errors",
    # OpenAPI schema
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

# =============================================================================
# CORS Settings
# =============================================================================
# Cross-Origin Resource Sharing configuration for API access

# Allow credentials (cookies, authorization headers)
CORS_ALLOW_CREDENTIALS = True

# Allow all origins (not recommended for production)
CORS_ALLOW_ALL_ORIGINS = config("CORS_ALLOW_ALL_ORIGINS", default=False, cast=bool)

# Specific allowed origins (comma-separated)
CORS_ALLOWED_ORIGINS = config(
    "CORS_ALLOWED_ORIGINS", default="", cast=lambda v: [s.strip() for s in v.split(",") if s.strip()]
)

# Allowed HTTP headers for CORS requests
CORS_ALLOW_HEADERS = [
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "origin",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
    "x-api-version",
]

# HTTP methods allowed for CORS requests
CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]

# Headers exposed to browsers (for rate limiting)
CORS_EXPOSE_HEADERS = [
    "X-RateLimit-Limit",
    "X-RateLimit-Remaining",
    "X-RateLimit-Reset",
    "X-API-Version",
]

# =============================================================================
# API Rate Limiting
# =============================================================================

API_RATE_LIMIT_PER_MINUTE = config("API_RATE_LIMIT_PER_MINUTE", default=60, cast=int)
API_RATE_LIMIT_PER_HOUR = config("API_RATE_LIMIT_PER_HOUR", default=1000, cast=int)

# =============================================================================
# SimpleJWT Settings
# =============================================================================
# JWT token configuration for authentication


# Import SECRET_KEY for signing tokens
# This will be set by base.py before this module is imported
def get_secret_key():
    """Get SECRET_KEY lazily to avoid circular imports."""
    return config("SECRET_KEY")


SIMPLE_JWT = {
    # Token lifetimes
    # Short access tokens (15 min) provide better security
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=config("JWT_ACCESS_TOKEN_LIFETIME_MINUTES", default=15, cast=int)),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=config("JWT_REFRESH_TOKEN_LIFETIME_DAYS", default=7, cast=int)),
    # Token rotation and blacklisting
    # Rotate refresh tokens on each use and blacklist old ones
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
    # Update last login on token refresh
    "UPDATE_LAST_LOGIN": True,
    # Cryptographic settings
    "ALGORITHM": "HS256",
    "SIGNING_KEY": None,  # Will use Django's SECRET_KEY
    "VERIFYING_KEY": None,
    # Token validation
    "AUDIENCE": None,
    "ISSUER": config("JWT_ISSUER", default="thrillwiki"),
    "JWK_URL": None,
    "LEEWAY": 0,  # No leeway for token expiration
    # Authentication header
    "AUTH_HEADER_TYPES": ("Bearer",),
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
    # User identification
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "USER_AUTHENTICATION_RULE": ("rest_framework_simplejwt.authentication.default_user_authentication_rule"),
    # Token classes
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
    # JTI claim for unique token identification (enables revocation)
    "JTI_CLAIM": "jti",
    # Sliding token settings
    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=15),
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
}

# =============================================================================
# dj-rest-auth Settings
# =============================================================================
# REST authentication endpoints configuration

# Determine if we're in debug mode for secure cookie setting
_debug = config("DEBUG", default=True, cast=bool)

REST_AUTH = {
    "USE_JWT": True,
    "JWT_AUTH_COOKIE": "thrillwiki-auth",
    "JWT_AUTH_REFRESH_COOKIE": "thrillwiki-refresh",
    # Only send cookies over HTTPS in production
    "JWT_AUTH_SECURE": not _debug,
    # Prevent JavaScript access to cookies
    "JWT_AUTH_HTTPONLY": True,
    # SameSite cookie attribute (Lax is compatible with OAuth flows)
    "JWT_AUTH_SAMESITE": "Lax",
    "JWT_AUTH_RETURN_EXPIRATION": True,
    "JWT_TOKEN_CLAIMS_SERIALIZER": ("rest_framework_simplejwt.serializers.TokenObtainPairSerializer"),
}

# =============================================================================
# drf-spectacular Settings (OpenAPI Documentation)
# =============================================================================

SPECTACULAR_SETTINGS = {
    "TITLE": "ThrillWiki API",
    "DESCRIPTION": """Comprehensive theme park and ride information API.

## API Conventions

### Response Format
All successful responses include a `success: true` field with data nested under `data`.
All error responses include an `error` object with `code` and `message` fields.

### Pagination
List endpoints support pagination with `page` and `page_size` parameters.
Default page size is 20, maximum is 100.

### Filtering
Range filters use `{field}_min` and `{field}_max` naming convention.
Search uses the `search` parameter.
Ordering uses the `ordering` parameter (prefix with `-` for descending).

### Field Naming
All field names use snake_case convention (e.g., `image_url`, `created_at`).
""",
    "VERSION": config("API_VERSION", default="1.0.0"),
    "SERVE_INCLUDE_SCHEMA": False,
    "COMPONENT_SPLIT_REQUEST": True,
    "TAGS": [
        {"name": "Parks", "description": "Theme park operations"},
        {"name": "Rides", "description": "Ride information and management"},
        {"name": "Park Media", "description": "Park photos and media management"},
        {"name": "Ride Media", "description": "Ride photos and media management"},
        {"name": "Authentication", "description": "User authentication and session management"},
        {"name": "Social Authentication", "description": "Social provider login and account linking"},
        {"name": "User Profile", "description": "User profile management"},
        {"name": "User Settings", "description": "User preferences and settings"},
        {"name": "User Notifications", "description": "User notification management"},
        {"name": "User Content", "description": "User-generated content (top lists, reviews)"},
        {"name": "User Management", "description": "Admin user management operations"},
        {"name": "Self-Service Account Management", "description": "User account deletion and management"},
        {"name": "Core", "description": "Core utility endpoints (search, suggestions)"},
        {"name": "Statistics", "description": "Statistical endpoints providing aggregated data and insights"},
    ],
    "SCHEMA_PATH_PREFIX": "/api/",
    "DEFAULT_GENERATOR_CLASS": "drf_spectacular.generators.SchemaGenerator",
    "DEFAULT_AUTO_SCHEMA": "drf_spectacular.openapi.AutoSchema",
    "PREPROCESSING_HOOKS": [
        "api.v1.schema.custom_preprocessing_hook",
    ],
    "SERVE_PERMISSIONS": ["rest_framework.permissions.AllowAny"],
    "SWAGGER_UI_SETTINGS": {
        "deepLinking": True,
        "persistAuthorization": True,
        "displayOperationId": False,
        "displayRequestDuration": True,
    },
    "REDOC_UI_SETTINGS": {
        "hideDownloadButton": False,
        "hideHostname": False,
        "hideLoading": False,
        "hideSchemaPattern": True,
        "scrollYOffset": 0,
        "theme": {"colors": {"primary": {"main": "#1976d2"}}},
    },
}
