from datetime import timedelta
from os import getenv
from typing import Any

from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _

from evibes.settings.base import (
    BASE_DOMAIN,
    DEBUG,
    EVIBES_VERSION,
    PROJECT_NAME,
    SECRET_KEY,
)

REST_FRAMEWORK: dict[str, Any] = {
    "DEFAULT_PAGINATION_CLASS": "evibes.pagination.CustomPagination",
    "PAGE_SIZE": 30,
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ],
    "DEFAULT_RENDERER_CLASSES": (
        "evibes.utils.renderers.CamelCaseRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    ),
    "DEFAULT_PARSER_CLASSES": ("evibes.utils.parsers.CamelCaseParser",),
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.generators.AutoSchema",
    "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.AllowAny",),
    "JSON_UNDERSCOREIZE": {
        "no_underscore_before_number": False,
    },
}

JSON_UNDERSCOREIZE: dict[str, Any] = REST_FRAMEWORK.get("JSON_UNDERSCOREIZE", ())

access_lifetime = timedelta(hours=8) if not DEBUG else timedelta(hours=88)
refresh_lifetime = timedelta(days=8)

SIMPLE_JWT: dict[str, timedelta | str | bool] = {
    "ACCESS_TOKEN_LIFETIME": access_lifetime,
    "REFRESH_TOKEN_LIFETIME": refresh_lifetime,
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
    "UPDATE_LAST_LOGIN": True,
    "SIGNING_KEY": getenv("JWT_SIGNING_KEY", SECRET_KEY),  # noqa: F405
    "USER_ID_FIELD": "uuid",
    "USER_ID_CLAIM": "user_uuid",
    "AUTH_HEADER_NAME": "HTTP_X_EVIBES_AUTH",
}

_SPECTACULAR_DESCRIPTION_TEMPLATE = _("""
Welcome to the eVibes documentation.

eVibes is a powerful e-commerce platform that allows you to launch and manage an online store of any kind in just a few clicks.

## Key Features
- **Product Catalog:** Manage product details, pricing, inventory, and availability across multiple categories.
- **Order Management:** Process orders, track fulfillment, and handle customer requests efficiently.
- **Authentication & Authorization:** Comprehensive user authentication with JWT tokens and role-based permissions.
- **Payment Processing:** Integrate multiple payment gateways and manage transactions securely.
- **Blog & Content Management:** Create and manage blog posts and marketing content for your store.
- **B2B Operations:** Dedicated endpoints for business-to-business transactions and wholesale management.
- **Multi-language Support:** Serve customers worldwide with full internationalization (i18n) capabilities.
- **Custom Integrations:** Extensible API architecture for integrating with external platforms and services.
- **Analytics & Reporting:** Generate detailed reports on sales, inventory, and customer behavior.
- **Real-Time Updates:** Get live data on inventory levels, order statuses, and pricing changes.

## Available APIs
- **REST API:** Full RESTful interface (this documentation)
- **GraphQL API:** Available at `/graphql/` with GraphiQL interface for interactive queries

## Authentication
- Authentication is handled via JWT tokens. Include the token in the `X-EVIBES-AUTH` header of your requests in the format `Bearer <your_token>`.
- Access token lifetime is {access_lifetime} {access_unit}.
- Refresh token lifetime is {refresh_hours} hours.
- Refresh tokens are automatically rotated and invalidated after usage for enhanced security.

## Internationalization (i18n)
- Set the `Accept-Language` header to specify your preferred language (e.g., `Accept-Language: en-US`).
- Available languages can be retrieved from the `/app/languages/` endpoint.
- All user-facing content supports multiple languages out of the box.

## Response Formats
The API supports multiple response formats:
- **JSON** (default, camelCase formatted)
- **XML** (add `?format=xml` or set `Accept: application/xml`)
- **YAML** (add `?format=yaml` or set `Accept: application/x-yaml`)

## Health & Monitoring
- Health checks: `/health/`
- Prometheus metrics: `/prometheus/metrics/`

## Version
Current API version: {version}
""")  # noqa: E501, F405

if not DEBUG:
    _access_lifetime = int(access_lifetime.total_seconds() // 60)
    _access_unit = "minutes"
else:
    _access_lifetime = int(access_lifetime.total_seconds() // 3600)
    _access_unit = "hours"

_refresh_hours = int(refresh_lifetime.total_seconds() // 3600)

SPECTACULAR_DESCRIPTION = format_lazy(
    _SPECTACULAR_DESCRIPTION_TEMPLATE,
    access_lifetime=_access_lifetime,
    access_unit=_access_unit,
    refresh_hours=_refresh_hours,
    version=EVIBES_VERSION,
)

SPECTACULAR_SETTINGS = {
    "OAS_VERSION": "3.1.0",
    "DEFAULT_GENERATOR_CLASS": "drf_spectacular_websocket.schemas.WsSchemaGenerator",
    "TITLE": f"{PROJECT_NAME} API",
    "DESCRIPTION": SPECTACULAR_DESCRIPTION,
    "VERSION": EVIBES_VERSION,  # noqa: F405
    "TOS": "https://evibes.wiseless.xyz/terms-of-service",
    "SWAGGER_UI_DIST": "SIDECAR",
    "CAMELIZE_NAMES": True,
    "POSTPROCESSING_HOOKS": [
        "evibes.utils.renderers.camelize_serializer_fields",
        "drf_spectacular.hooks.postprocess_schema_enums",
    ],
    "REDOC_DIST": "SIDECAR",
    "ENABLE_DJANGO_DEPLOY_CHECK": not DEBUG,  # noqa: F405
    "SWAGGER_UI_FAVICON_HREF": r"/static/favicon.png",
    "SWAGGER_UI_SETTINGS": {
        "connectSocket": False,
        "socketMaxMessages": 8,
        "socketMessagesInitialOpened": False,
    },
    "SERVERS": [
        {
            "url": f"https://api.{BASE_DOMAIN}/",
            "description": "Production Server",
        },
        {"url": "http://localhost:8000/", "description": "Development Server"},
    ],
    "CONTACT": {
        "name": 'Egor "fureunoir" Gorbunov',
        "email": "contact@fureunoir.com",
        "url": "https://t.me/fureunoir",
    },
    "ENUM_NAME_OVERRIDES": {
        "OrderStatusEnum": "engine.core.choices.ORDER_STATUS_CHOICES",
        "OrderProductStatusEnum": "engine.core.choices.ORDER_PRODUCT_STATUS_CHOICES",
        "TransactionStatusEnum": "engine.core.choices.TRANSACTION_STATUS_CHOICES",
        "ThreadStatusEnum": "engine.vibes_auth.choices.ThreadStatus",
    },
}
