import os
import sys
from datetime import timedelta
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

try:
    from dotenv import load_dotenv

    load_dotenv(BASE_DIR / ".env")
except ImportError:
    pass

SECRET_KEY = os.environ.get(
    "DJANGO_SECRET_KEY", "dev-insecure-change-me-in-production-use-env"
)

DEBUG = os.environ.get("DJANGO_DEBUG", "true").lower() in ("1", "true", "yes")

_allowed_hosts = os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1").split(",")
ALLOWED_HOSTS = [h.strip() for h in _allowed_hosts if h.strip()]
for host in ("192.168.1.8", "95.104.225.67", "finuniver-perm.ru", "www.finuniver-perm.ru"):
    if host not in ALLOWED_HOSTS:
        ALLOWED_HOSTS.append(host)
if DEBUG and "testserver" not in ALLOWED_HOSTS:
    ALLOWED_HOSTS.append("testserver")

_trusted_origins = os.environ.get(
    "CSRF_TRUSTED_ORIGINS",
    "https://finuniver-perm.ru,https://www.finuniver-perm.ru,https://95.104.225.67,https://192.168.1.8",
).split(",")
CSRF_TRUSTED_ORIGINS = [u.strip() for u in _trusted_origins if u.strip()]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "rest_framework_simplejwt",
    "rest_framework_simplejwt.token_blacklist",
    "corsheaders",
    "drf_spectacular",
    "users",
    "portfolio",
    "resume",
]

INSTALLED_APPS.append("tests.apps.ProjectTestsConfig")

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "portfolio_system.middleware.BlockProbeRequestsMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "portfolio_system.urls"

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",
            ],
        },
    },
]

WSGI_APPLICATION = "portfolio_system.wsgi.application"

# Только MySQL. Задайте переменные в .env (см. .env.example).
_mysql_db = os.environ.get("MYSQL_DATABASE", "").strip()
_mysql_user = os.environ.get("MYSQL_USER", "").strip()
_mysql_host = os.environ.get("MYSQL_HOST", "").strip()
if not _mysql_db or not _mysql_user or not _mysql_host:
    if os.environ.get("DJANGO_SKIP_MYSQL_CHECK") != "1":
        from django.core.exceptions import ImproperlyConfigured

        raise ImproperlyConfigured(
            "Укажите MYSQL_DATABASE, MYSQL_USER и MYSQL_HOST (файл .env в корне проекта). "
            "SQLite отключён."
        )

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": _mysql_db,
        "USER": _mysql_user,
        "PASSWORD": os.environ.get("MYSQL_PASSWORD", ""),
        "HOST": _mysql_host,
        "PORT": os.environ.get("MYSQL_PORT", "3306"),
        "OPTIONS": {
            "charset": "utf8mb4",
            "init_command": (
                "SET sql_mode='STRICT_TRANS_TABLES', "
                "NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"
            ),
        },
    }
}

# Если у пользователя MySQL нет права CREATE DATABASE для автотестов, создайте пустую БД
# вручную и укажите имя здесь (например test_DB_411_12).
_mysql_test = os.environ.get("MYSQL_TEST_DATABASE", "").strip()
if _mysql_test:
    DATABASES["default"]["TEST"] = {"NAME": _mysql_test}

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"},
]

LANGUAGE_CODE = "ru-ru"
TIME_ZONE = "Europe/Moscow"
USE_I18N = True
USE_TZ = True

STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"

MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

AUTH_USER_MODEL = "users.User"

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
    "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
    "DEFAULT_PARSER_CLASSES": (
        "rest_framework.parsers.JSONParser",
        "rest_framework.parsers.MultiPartParser",
        "rest_framework.parsers.FormParser",
    ),
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
    "EXCEPTION_HANDLER": "portfolio_system.exceptions.custom_exception_handler",
}

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=60),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=7),
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
}

_cors = os.environ.get(
    "CORS_ALLOWED_ORIGINS",
    "http://localhost:8000,http://127.0.0.1:8000",
)
CORS_ALLOWED_ORIGINS = [u.strip() for u in _cors.split(",") if u.strip()]
CORS_ALLOW_CREDENTIALS = True

EMAIL_BACKEND = os.environ.get(
    "EMAIL_BACKEND", "django.core.mail.backends.console.EmailBackend"
)
DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", "noreply@portfolio.local")
FRONTEND_URL = os.environ.get("FRONTEND_URL", "http://127.0.0.1:8000")

LOGIN_URL = "/login/"

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "portfolio-ratelimit",
        "TIMEOUT": 300,
    }
}

RATELIMIT_USE_CACHE = "default"
RATELIMIT_ENABLE = os.environ.get("RATELIMIT_ENABLE", "true").lower() in (
    "1",
    "true",
    "yes",
)

SPECTACULAR_SETTINGS = {
    "TITLE": "Цифровое студенческое портфолио API",
    "VERSION": "1.0.0",
    "SERVE_INCLUDE_SCHEMA": False,
}

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "verbose": {
            "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "verbose",
            "stream": sys.stdout,
        },
    },
    "root": {
        "handlers": ["console"],
        "level": os.environ.get("DJANGO_LOG_LEVEL", "INFO"),
    },
    "filters": {
        "suppress_probe_404": {
            "()": "portfolio_system.logging_filters.SuppressProbe404Filter",
        },
    },
    "loggers": {
        "django.request": {
            "handlers": ["console"],
            "level": "WARNING",
            "propagate": False,
            "filters": ["suppress_probe_404"],
        },
        "django.security": {"handlers": ["console"], "level": "WARNING", "propagate": False},
    },
}

if not DEBUG:
    _secure = os.environ.get("DJANGO_SECURE_COOKIES", "false").lower() in (
        "1",
        "true",
        "yes",
    )
    if _secure:
        SESSION_COOKIE_SECURE = True
        CSRF_COOKIE_SECURE = True
    SECURE_BROWSER_XSS_FILTER = True
    SECURE_CONTENT_TYPE_NOSNIFF = True
    X_FRAME_OPTIONS = "DENY"
    if os.environ.get("DJANGO_SECURE_SSL_REDIRECT", "false").lower() in ("1", "true", "yes"):
        SECURE_SSL_REDIRECT = True
        
# Исправление сдвоенного IP для django-ratelimit за прокси Nginx + Unix-сокет Gunicorn
def _extract_client_ip(request):
    """Первый валидный IP из X-Forwarded-For или REMOTE_ADDR (без CIDR-маски)."""
    import ipaddress

    sources = []
    forwarded = (request.META.get("HTTP_X_FORWARDED_FOR") or "").strip()
    if forwarded:
        sources.extend(part.strip() for part in forwarded.split(",") if part.strip())
    remote = (request.META.get("REMOTE_ADDR") or "").strip()
    if remote:
        sources.append(remote)

    for candidate in sources:
        ip = candidate
        if "/" in ip:
            ip = ip.split("/", 1)[0].strip()
        try:
            ipaddress.ip_address(ip)
            return ip
        except ValueError:
            continue
    return "127.0.0.1"


RATELIMIT_IP_META_KEY = lambda request: _extract_client_ip(request)

