"""
config/settings/base.py
========================
Configuración BASE compartida por todos los entornos (development, production).
Aquí van SOLO los ajustes que no varían entre entornos.
Las credenciales y valores sensibles se leen de variables de entorno
mediante python-decouple para no hardcodear nada en el repositorio.
"""

import os
from pathlib import Path
from decouple import config, Csv
from datetime import timedelta

# ─────────────────────────────────────────────────────────────
# RUTAS BASE
# ─────────────────────────────────────────────────────────────
BASE_DIR = Path(__file__).resolve().parent.parent.parent

# ─────────────────────────────────────────────────────────────
# CLAVE SECRETA — NUNCA hardcodear, siempre desde .env
# ─────────────────────────────────────────────────────────────
SECRET_KEY = config('SECRET_KEY')

# ─────────────────────────────────────────────────────────────
# APLICACIONES INSTALADAS
# Se separan por origen para facilitar el mantenimiento:
#   - Django core
#   - Librerías de terceros
#   - Apps propias del proyecto
# ─────────────────────────────────────────────────────────────
DJANGO_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

THIRD_PARTY_APPS = [
    'rest_framework',           # Django REST Framework
    'rest_framework_simplejwt', # Autenticación JWT
    'corsheaders',              # CORS para el frontend React
    'channels',                 # WebSockets para sesiones en vivo
]

LOCAL_APPS = [
    'users',        # Gestión de usuarios y roles
    'academic',     # Asignaturas, secciones, inscripciones
    'questions',    # Banco de preguntas
    'sessions',     # Sesiones en vivo (clase y exposición)
    'gamification', # Puntos, insignias, fichas, temporadas
    'evaluation',   # Notas, décimas, actas
    'analytics',    # Analítica pedagógica y alertas
    'security',     # Auditoría, rate limiting, anti-trampa
]

INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

# ─────────────────────────────────────────────────────────────
# MIDDLEWARE
# El orden importa: CorsMiddleware debe ir ANTES de CommonMiddleware
# ─────────────────────────────────────────────────────────────
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',        # CORS — debe ser primero
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'security.middleware.RateLimitMiddleware',       # Rate limiting propio
    'security.middleware.AuditMiddleware',           # Log de auditoría
    'security.middleware.SessionUniquenessMiddleware', # 1 sesión por usuario
]

# ─────────────────────────────────────────────────────────────
# URLS Y WSGI / ASGI
# ─────────────────────────────────────────────────────────────
ROOT_URLCONF = 'config.urls'
WSGI_APPLICATION = 'config.wsgi.application'
ASGI_APPLICATION = 'config.asgi.application'  # Django Channels

# ─────────────────────────────────────────────────────────────
# TEMPLATES (necesario para Django Admin)
# ─────────────────────────────────────────────────────────────
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        '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',
            ],
        },
    },
]

# ─────────────────────────────────────────────────────────────
# BASE DE DATOS — MySQL (cPanel)
# Las credenciales vienen de .env, nunca hardcodeadas
# ─────────────────────────────────────────────────────────────
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':     config('DB_NAME'),
        'USER':     config('DB_USER'),
        'PASSWORD': config('DB_PASSWORD'),
        'HOST':     config('DB_HOST', default='localhost'),
        'PORT':     config('DB_PORT', default='3306'),
        'OPTIONS': {
            'charset': 'utf8mb4',           # Soporte completo Unicode + emojis
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            'connect_timeout': 10,
        },
        'CONN_MAX_AGE': 60,                 # Conexiones persistentes (60 seg)
    }
}

# ─────────────────────────────────────────────────────────────
# MODELO DE USUARIO PERSONALIZADO
# Reemplaza al User de Django por el nuestro con roles y campos extra
# ─────────────────────────────────────────────────────────────
AUTH_USER_MODEL = 'users.CustomUser'

# ─────────────────────────────────────────────────────────────
# CONTRASEÑAS — Validadores de complejidad
# ─────────────────────────────────────────────────────────────
AUTH_PASSWORD_VALIDATORS = [
    {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
    {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
     'OPTIONS': {'min_length': 8}},
    {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
    {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
]

# ─────────────────────────────────────────────────────────────
# INTERNACIONALIZACIÓN
# ─────────────────────────────────────────────────────────────
LANGUAGE_CODE = 'es-cl'
TIME_ZONE = 'America/Santiago'
USE_I18N = True
USE_TZ = True  # Siempre almacenar en UTC, convertir para mostrar

# ─────────────────────────────────────────────────────────────
# ARCHIVOS ESTÁTICOS Y MEDIA
# ─────────────────────────────────────────────────────────────
STATIC_URL  = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
MEDIA_URL   = '/media/'
MEDIA_ROOT  = BASE_DIR / 'media'

# ─────────────────────────────────────────────────────────────
# CAMPO AUTO POR DEFECTO
# ─────────────────────────────────────────────────────────────
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# ─────────────────────────────────────────────────────────────
# DJANGO REST FRAMEWORK
# Configuración global de la API REST
# ─────────────────────────────────────────────────────────────
REST_FRAMEWORK = {
    # Autenticación: JWT por defecto, sesión para admin
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ],
    # Por defecto todos los endpoints requieren autenticación
    # Cada vista puede relajar esto con permission_classes propio
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    # Paginación global: 20 ítems por página, configurable por vista
    'DEFAULT_PAGINATION_CLASS': 'shared.pagination.StandardPagination',
    'PAGE_SIZE': 20,
    # Throttling global — se complementa con el middleware RateLimit
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '30/minute',
        'user': '200/minute',
    },
    # Renderers: JSON en producción, + Browsable en dev
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    # Parser: aceptar JSON y multipart (para importación de archivos)
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.MultiPartParser',
    ],
    # Manejo de excepciones personalizado para respuestas uniformes
    'EXCEPTION_HANDLER': 'shared.utils.exception_handler.custom_exception_handler',
    # Formato de fecha/hora en respuestas
    'DATETIME_FORMAT': '%Y-%m-%dT%H:%M:%SZ',
}

# ─────────────────────────────────────────────────────────────
# JWT — Configuración de tokens de acceso y refresco
# ─────────────────────────────────────────────────────────────
SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME':  timedelta(minutes=15),   # Token de acceso: 15 min
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),        # Token de refresco: 7 días
    'ROTATE_REFRESH_TOKENS':  True,    # Nuevo refresh token en cada uso
    'BLACKLIST_AFTER_ROTATION': True,  # Invalida el anterior
    'UPDATE_LAST_LOGIN': True,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': config('JWT_SECRET_KEY', default=SECRET_KEY),
    'AUTH_HEADER_TYPES': ('Bearer',),
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    # Claims extra: incluir rol en el token para validación rápida sin BD
    # Nota: el login usa LoginView con CustomTokenObtainSerializer propio,
    # no el endpoint /token/ de simplejwt — por eso no se configura TOKEN_OBTAIN_SERIALIZER
}

# ─────────────────────────────────────────────────────────────
# DJANGO CHANNELS — WebSockets para sesiones en vivo
# En producción usar Redis como channel layer
# ─────────────────────────────────────────────────────────────
CHANNEL_LAYERS = {
    'default': {
        # InMemoryChannelLayer para dev/producción sin Redis
        # Para escalar: cambiar a channels_redis.core.RedisChannelLayer
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
    }
}

# ─────────────────────────────────────────────────────────────
# CORS — Orígenes permitidos para el frontend React
# En producción esto se sobreescribe con el dominio real
# ─────────────────────────────────────────────────────────────
CORS_ALLOWED_ORIGINS = config('CORS_ORIGINS', default='http://localhost:5173', cast=Csv())
CORS_ALLOW_CREDENTIALS = True  # Necesario para cookies de refresh token

# ─────────────────────────────────────────────────────────────
# SEGURIDAD — Configuración del módulo propio
# ─────────────────────────────────────────────────────────────
SECURITY_CONFIG = {
    # Intentos de login fallidos antes de bloquear IP
    'MAX_LOGIN_ATTEMPTS': 5,
    # Minutos de bloqueo tras superar intentos
    'LOCKOUT_DURATION_MINUTES': 30,
    # Tiempo en segundos antes de aceptar códigos de acceso (anti-bot)
    'CODE_MIN_SUBMISSION_TIME': 3,
    # Máx. intentos de usar código de acceso por IP / 5 min
    'CODE_MAX_ATTEMPTS': 10,
    # Tiempo en milisegundos mínimo para considerar respuesta válida
    'SUSPICIOUS_RESPONSE_TIME_MS': 1500,
    # Días de retención de logs de auditoría antes de archivar
    'AUDIT_RETENTION_DAYS': 90,
    # Expiración del código de acceso efímero (minutos)
    'ACCESS_CODE_EXPIRY_MINUTES': 20,
    # Expiración del código de registro de alumno (horas)
    'REGISTRATION_CODE_EXPIRY_HOURS': 72,
}

# ─────────────────────────────────────────────────────────────
# CIFRADO — Clave AES-256 para datos personales en BD
# Se genera una vez y se guarda en .env
# ─────────────────────────────────────────────────────────────
ENCRYPTION_KEY = config('ENCRYPTION_KEY')  # 32 bytes en base64

# ─────────────────────────────────────────────────────────────
# LOGGING — Configuración base (se puede extender por entorno)
# ─────────────────────────────────────────────────────────────
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '[{asctime}] {levelname} {name} {message}',
            'style': '{',
        },
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR / 'logs' / 'eduplay.log',
            'maxBytes': 10 * 1024 * 1024,  # 10 MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'django': {'handlers': ['console'], 'level': 'WARNING'},
        'eduplay': {'handlers': ['console', 'file'], 'level': 'INFO', 'propagate': False},
        'security': {'handlers': ['console', 'file'], 'level': 'INFO', 'propagate': False},
    },
}
