"""
Django settings for rail_django_graphql project.

Generated by 'django-admin startproject' using Django 4.2.13.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-6uzw8)g9j8+vfow(c#+wlhwi^_r8+x0n-or$-^atg@q&#x()0n"

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # Third-party apps
    "graphene_django",
    "django_filters",
    "corsheaders",
    # Local apps
    "rail_django_graphql",
    "rail_django_graphql.core",
    "rail_django_graphql.generators",
    "rail_django_graphql.extensions",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",  # CORS middleware
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "rail_django_graphql.middleware.performance.GraphQLPerformanceMiddleware",
    "cache_middleware.GraphQLCacheInvalidationMiddleware",  # Cache invalidation middleware
]

ROOT_URLCONF = "rail_django_graphql.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

WSGI_APPLICATION = "rail_django_graphql.wsgi.application"


# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}


# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]


# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = "static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# GraphQL settings
GRAPHENE = {
    "SCHEMA": "rail_django_graphql.schema.schema",
    "SCHEMA_OUTPUT": "schema.graphql",  # Optional: output the schema in SDL format
    "SCHEMA_INDENT": 2,  # Optional: pretty formatting for schema output
    "MIDDLEWARE": [
        "graphene_django.debug.DjangoDebugMiddleware",
    ],
    "CAMELCASE_ERRORS": False,  # Keep error messages in snake_case
    "ATOMIC_MUTATIONS": True,  # Wrap mutations in transactions
}

# CORS settings
CORS_ALLOW_ALL_ORIGINS = True  # Only for development
CORS_ALLOWED_ORIGINS = [
    "http://localhost:8000",
    "http://127.0.0.1:8000",
]

# Logging configuration
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {
            "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "verbose",
        },
        "file": {
            "class": "logging.FileHandler",
            "filename": os.path.join(BASE_DIR, "logs", "django.log"),
            "formatter": "verbose",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console", "file"],
            "level": "INFO",
            "propagate": True,
        },
        "rail_django_graphql": {
            "handlers": ["console", "file"],
            "level": "DEBUG",
            "propagate": True,
        },
    },
}

RAIL_DJANGO_GRAPHQL = {
    # ========================================
    # CONFIGURATION GÉNÉRALE DU SCHÉMA
    # ========================================
    "schema_settings": {
        # Répertoire de sortie pour les schémas générés
        "schema_output_dir": "generated_schema/",
        # Génération automatique du schéma GraphQL
        "auto_generate_schema": True,
        # Convention de nommage pour les champs GraphQL (snake_case, camelCase)
        "naming_convention": "snake_case",
        # Activer l'introspection GraphQL (utile pour le développement)
        "enable_introspection": True,
        # Activer l'interface GraphiQL/Playground
        "enable_playground": DEBUG,
        # Mode debug pour des messages d'erreur détaillés
        "debug_mode": True,
        # Messages d'erreur verbeux
        "verbose_errors": True,
        # Applications à inclure (vide = toutes les applications)
        "apps_to_include": [],
        # Applications à exclure de la génération du schéma
        "apps_to_exclude": ["admin", "auth", "contenttypes", "sessions"],
        # Modèles spécifiques à exclure
        "models_to_exclude": ["LogEntry", "Session"],
        # Activer les mutations GraphQL
        "enable_mutations": True,
        # Activer les abonnements GraphQL (subscriptions)
        "enable_subscriptions": False,
        # Activer le système de filtrage avancé
        "enable_filters": True,
        # Activer les opérations imbriquées (nested operations)
        "enable_nested_operations": True,
        # Activer le téléchargement de fichiers
        "enable_file_uploads": True,
        # Activer les scalaires personnalisés
        "enable_custom_scalars": True,
        # Activer la prise en charge de l'héritage de modèles
        "enable_inheritance": True,
    },
    # ========================================
    # CONFIGURATION DES REQUÊTES
    # ========================================
    "query_settings": {
        # Utiliser les connexions Relay pour la pagination
        "use_relay": False,
        # Activer la génération de filtres pour les requêtes
        "generate_filters": True,
        # Activer le tri des résultats
        "generate_ordering": True,
        # Activer la pagination
        "generate_pagination": True,
        "enable_pagination": True,
        # Activer le tri (alias pour generate_ordering)
        "enable_ordering": True,
        # Taille de page par défaut
        "default_page_size": 20,
        # Taille de page maximale
        "max_page_size": 100,
        # Champs de recherche supplémentaires
        "additional_lookup_fields": {
            # Exemple: "User": ["email", "username"]
        },
    },
    # ========================================
    # CONFIGURATION DES MUTATIONS
    # ========================================
    "mutation_settings": {
        # Activer la génération de mutations de création
        "generate_create": True,
        "enable_create": True,
        # Activer la génération de mutations de mise à jour
        "generate_update": True,
        "enable_update": True,
        # Activer la génération de mutations de suppression
        "generate_delete": True,
        "enable_delete": True,
        # Activer les opérations en lot (bulk operations)
        "generate_bulk": True,
        "enable_bulk_operations": True,
        # Activer les mutations de méthodes personnalisées
        "enable_method_mutations": True,
        # Préfixe pour les mutations de méthodes
        "method_mutation_prefix": "",
        # Inclure les méthodes privées dans les mutations
        "include_private_methods": False,
        # Taille de lot par défaut pour les opérations en lot
        "bulk_batch_size": 100,
        # Nombre maximum d'objets pour les opérations en lot
        "bulk_max_objects": 1000,
        # Timeout pour les transactions en lot (en secondes)
        "bulk_transaction_timeout": 30,
        # Limitation du taux pour les opérations en lot
        "bulk_rate_limit": {
            "max_operations_per_minute": 10,
            "max_objects_per_hour": 10000,
        },
        # Champs requis pour les mutations de mise à jour
        "required_update_fields": {
            # Exemple: "User": ["email"]
        },
        # Activer les relations imbriquées dans les mutations
        "enable_nested_relations": True,
        # Configuration des relations imbriquées
        "nested_relations_config": {
            # Profondeur maximale des relations imbriquées
            "max_depth": 3,
            # Activer la création en cascade
            "enable_cascade_create": True,
        },
        # Configuration des champs imbriqués par modèle
        "nested_field_config": {
            "Post": {
                "category": True,  # Activer les opérations imbriquées pour category
                "tags": {
                    "enable_create": False,
                    "enable_update": False,
                },
            },
            # Ajouter d'autres modèles selon les besoins
        },
    },
    # ========================================
    # CONFIGURATION DES TYPES
    # ========================================
    "TYPE_SETTINGS": {
        # Champs à exclure globalement
        "exclude_fields": {
            # Exemple: "User": ["password", "last_login"]
        },
        "excluded_fields": {
            # Alias pour exclude_fields (rétrocompatibilité)
        },
        # Champs à inclure spécifiquement
        "include_fields": {
            # Exemple: "User": ["id", "username", "email"]
        },
        # Mappages de champs personnalisés
        "custom_field_mappings": {
            # Exemple: "User.profile_picture": "String"
        },
        # Générer des filtres pour les types
        "generate_filters": True,
        "enable_filtering": True,
        # Conversion automatique en camelCase
        "auto_camelcase": False,
        # Générer des descriptions pour les champs
        "generate_descriptions": True,
    },
    # ========================================
    # CONFIGURATION DU FILTRAGE
    # ========================================
    "FILTERING": {
        # Activer le système de filtrage
        "ENABLE_FILTERS": True,
        # Opérateurs de filtre par défaut pour chaque type de champ
        "DEFAULT_FILTER_OPERATORS": {
            "CharField": [
                "exact",
                "icontains",
                "startswith",
                "endswith",
                "iexact",
                "contains",
                "istartswith",
                "iendswith",
                "regex",
                "iregex",
                "in",
                "isnull",
            ],
            "TextField": [
                "exact",
                "icontains",
                "startswith",
                "endswith",
                "iexact",
                "contains",
                "istartswith",
                "iendswith",
                "regex",
                "iregex",
                "in",
                "isnull",
            ],
            "IntegerField": [
                "exact",
                "gt",
                "gte",
                "lt",
                "lte",
                "range",
                "in",
                "isnull",
            ],
            "FloatField": ["exact", "gt", "gte", "lt", "lte", "range", "in", "isnull"],
            "DecimalField": [
                "exact",
                "gt",
                "gte",
                "lt",
                "lte",
                "range",
                "in",
                "isnull",
            ],
            "BooleanField": ["exact", "isnull"],
            "DateTimeField": [
                "exact",
                "gt",
                "gte",
                "lt",
                "lte",
                "range",
                "date",
                "year",
                "month",
                "day",
                "week",
                "week_day",
                "quarter",
                "time",
                "hour",
                "minute",
                "second",
                "isnull",
            ],
            "DateField": [
                "exact",
                "gt",
                "gte",
                "lt",
                "lte",
                "range",
                "year",
                "month",
                "day",
                "week",
                "week_day",
                "quarter",
                "isnull",
            ],
            "TimeField": [
                "exact",
                "gt",
                "gte",
                "lt",
                "lte",
                "range",
                "hour",
                "minute",
                "second",
                "isnull",
            ],
        },
        # Activer les opérateurs logiques (AND, OR, NOT)
        "ENABLE_LOGICAL_OPERATORS": True,
        # Activer les filtres sur les relations
        "ENABLE_RELATIONSHIP_FILTERS": True,
        # Profondeur maximale des filtres imbriqués
        "MAX_FILTER_DEPTH": 3,
        # Activer les filtres personnalisés
        "ENABLE_CUSTOM_FILTERS": True,
        # Définition des filtres personnalisés
        "CUSTOM_FILTERS": {
            # Exemple: "search": "icontains"
        },
        # Activer la mise en cache des filtres
        "ENABLE_FILTER_CACHING": True,
        # Timeout du cache des filtres (en secondes)
        "FILTER_CACHE_TIMEOUT": 300,
        # Préfixe des clés de cache pour les filtres
        "FILTER_CACHE_KEY_PREFIX": "graphql_filter",
    },
    # ========================================
    # CONFIGURATION DE LA PAGINATION
    # ========================================
    "PAGINATION": {
        # Taille de pagination par défaut
        "PAGINATION_SIZE": 20,
        "DEFAULT_PAGE_SIZE": 20,
        # Taille de page maximale
        "MAX_PAGE_SIZE": 100,
        # Utiliser la pagination Relay
        "USE_RELAY_PAGINATION": False,
        # Activer la pagination par curseur
        "ENABLE_CURSOR_PAGINATION": True,
        # Activer la pagination par offset
        "ENABLE_OFFSET_PAGINATION": True,
    },
    # ========================================
    # CONFIGURATION DE LA SÉCURITÉ
    # ========================================
    "SECURITY": {
        # Profondeur maximale des requêtes
        "MAX_QUERY_DEPTH": 10,
        # Complexité maximale des requêtes
        "MAX_QUERY_COMPLEXITY": 1000,
        # Activer l'analyse du coût des requêtes
        "QUERY_COST_ANALYSIS": True,
        # Timeout des requêtes (en secondes)
        "QUERY_TIMEOUT": 30,
        # Permissions pour les mutations
        "MUTATION_PERMISSIONS": {
            # Exemple: "User": ["create", "update", "delete"]
        },
        # Champs sensibles à masquer
        "SENSITIVE_FIELDS": {
            # Exemple: "User": ["password", "secret_key"]
        },
        # Permissions par champ
        "FIELD_PERMISSIONS": {
            # Exemple: "User.email": ["authenticated"]
        },
    },
    # ========================================
    # CONFIGURATION DES PERFORMANCES
    # ========================================
    "PERFORMANCE": {
        # Activer l'optimisation des requêtes
        "ENABLE_QUERY_OPTIMIZATION": True,
        # Activer la mise en cache du schéma
        "ENABLE_SCHEMA_CACHING": True,
        # Timeout du cache du schéma (en secondes)
        "SCHEMA_CACHE_TIMEOUT": 3600,
        # Activer le monitoring des performances
        "PERFORMANCE_MONITORING": True,
        # Seuil pour les requêtes lentes (en millisecondes)
        "SLOW_QUERY_THRESHOLD": 1000,
        # Activer la compression des réponses
        "ENABLE_RESPONSE_COMPRESSION": True,
        # Tailles de lot spécifiques par modèle
        "MODEL_SPECIFIC_BATCH_SIZES": {
            # Exemple: "User": 50, "Post": 100
        },
    },
    # ========================================
    # SCALAIRES ET CONVERTISSEURS PERSONNALISÉS
    # ========================================
    "CUSTOM_SCALARS": {
        # Exemple: "DateTime": "graphene.DateTime",
        # "JSON": "graphene_django.extras.DjangoJSONType",
        # "Upload": "graphene_file_upload.scalars.Upload",
    },
    "FIELD_CONVERTERS": {
        # Exemple: "models.JSONField": "graphene.JSONString"
    },
    # ========================================
    # HOOKS ET MIDDLEWARE
    # ========================================
    "SCHEMA_HOOKS": [
        # Exemple: "myapp.hooks.pre_schema_build",
        # "myapp.hooks.post_schema_build",
    ],
    "MIDDLEWARE": [
        # Exemple: "myapp.middleware.CustomGraphQLMiddleware",
    ],
    # ========================================
    # OPÉRATIONS IMBRIQUÉES AVANCÉES
    # ========================================
    "NESTED_OPERATIONS": {
        # Activer les opérations imbriquées
        "ENABLE_NESTED_CREATE": True,
        "ENABLE_NESTED_UPDATE": True,
        "ENABLE_NESTED_DELETE": True,
        # Seuil pour les opérations en lot
        "BULK_THRESHOLD": 10,
        "MAX_NESTING_DEPTH": 5,
        "ENABLE_QUERY_OPTIMIZATION": True,
        # Vérifications de sécurité pour les suppressions
        "ENABLE_DELETION_SAFETY_CHECKS": True,
        "DEFAULT_DELETE_PROTECTION": True,
        "REQUIRE_EXPLICIT_CASCADE": True,
        # Validation des opérations imbriquées
        "ENABLE_NESTED_VALIDATION": True,
        "VALIDATE_RELATIONSHIPS": True,
        "STRICT_TYPE_CHECKING": True,
        # Gestion des transactions
        "USE_TRANSACTIONS": True,
        "TRANSACTION_ISOLATION_LEVEL": "READ_COMMITTED",
    },
    "RELATIONSHIP_HANDLING": {
        # Comportement par défaut pour les suppressions de relations
        "FOREIGN_KEY_ON_DELETE": "protect",
        "ONE_TO_MANY_ON_DELETE": "cascade",
        "MANY_TO_MANY_ON_DELETE": "clear",
        # Comportement par défaut pour les mises à jour de relations
        "FOREIGN_KEY_ON_UPDATE": "update",
        "ONE_TO_MANY_ON_UPDATE": "merge",
        "MANY_TO_MANY_ON_UPDATE": "replace",
    },
    # ========================================
    # CONFIGURATION DE DÉVELOPPEMENT/TEST
    # ========================================
    "DEVELOPMENT": {
        # Mode test (désactive certaines fonctionnalités coûteuses)
        "TESTING": False,
        # Désactiver la mise en cache en développement
        "CACHE_ENABLED": True,
        # Taille de page réduite pour les tests
        "TEST_PAGE_SIZE": 5,
        # Activer les logs détaillés
        "VERBOSE_LOGGING": True,
        # Activer le rechargement automatique du schéma
        "AUTO_RELOAD_SCHEMA": True,
    },
    # ========================================
    # INTERNATIONALISATION
    # ========================================
    "I18N": {
        # Activer l'internationalisation
        "ENABLE_I18N": True,
        # Langues supportées
        "SUPPORTED_LANGUAGES": ["fr", "en"],
        # Langue par défaut
        "DEFAULT_LANGUAGE": "fr",
        # Champs traduisibles
        "TRANSLATABLE_FIELDS": {
            # Exemple: "Post": ["title", "content"]
        },
    },
}
