# django_core_micha/settings_base.py

from corsheaders.defaults import default_headers
from django.conf import settings
import environ
import os
import logging

logger = logging.getLogger("backend")

# -------------------------------------------------------------------
# Environment
# -------------------------------------------------------------------

env = environ.Env(
    DEBUG=(bool, False),
    EMAIL_PORT=(int, 587),
    EMAIL_USE_TLS=(bool, True),
)

DEBUG = env("DEBUG", default=False)

# 1) Environment type: local / staging / production / edge / ...
ENV_TYPE = env("ENV_TYPE", default="local").lower()

SYNC_SHARED_SECRET = env("SYNC_SHARED_SECRET", default=None)

SECRET_KEY = env("DJANGO_SECRET_KEY", default="local-dev-secret-key")

# 2) Origin server id
ORIGIN_SERVER_ID = os.environ.get("ORIGIN_SERVER_ID")

if not ORIGIN_SERVER_ID:
    if ENV_TYPE == "production":
        ORIGIN_SERVER_ID = "MASTER-UNKNOWN"
    elif ENV_TYPE == "staging":
        ORIGIN_SERVER_ID = "STAGING-UNKNOWN"
    else:
        ORIGIN_SERVER_ID = "DEV-LOCAL"

# 3) Bequeme Flags
IS_PRODUCTION = ENV_TYPE == "production"
IS_STAGING = ENV_TYPE == "staging"
IS_LOCAL = ENV_TYPE == "local"
IS_EDGE = ENV_TYPE == "edge" 

IS_MASTER = IS_PRODUCTION and ORIGIN_SERVER_ID.upper().startswith("MASTER")


logger.info(f"Starting with ENV_TYPE={ENV_TYPE}, ORIGIN_SERVER_ID={ORIGIN_SERVER_ID}, IS_MASTER={IS_MASTER}, IS_EDGE={IS_EDGE}, DEBUG={DEBUG}")

DEEPL_API_KEY = os.getenv("DEEPL_API_KEY", "")


# -------------------------------------------------------------------
# Hosts & Networking
# -------------------------------------------------------------------

ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[])
CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_URLS", default=[])
CORS_ALLOWED_ORIGINS = CSRF_TRUSTED_ORIGINS
PUBLIC_ORIGIN = env("PUBLIC_ORIGIN", default="http://localhost:3000")

if not IS_LOCAL:
    SECURE_HSTS_SECONDS = 31536000
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
    SECURE_HSTS_PRELOAD = True
    SECURE_SSL_REDIRECT = True
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
    SECURE_REFERRER_POLICY = "same-origin"

SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_SECURE = not IS_LOCAL
CSRF_COOKIE_SECURE = not IS_LOCAL

# -------------------------------------------------------------------
# Applications
# -------------------------------------------------------------------

CORE_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
    # Third-party
    "corsheaders",
    "rest_framework",
    "channels",
    "allauth",
    "allauth.mfa",
    "allauth.account",
    "allauth.socialaccount",
    "allauth.socialaccount.providers.google",
    "allauth.socialaccount.providers.microsoft",
    # Core app(s)
    "django_core_micha.invitations",
    "django_core_micha.auth",
]

INSTALLED_APPS = CORE_APPS.copy()

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
    "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",
    "allauth.account.middleware.AccountMiddleware",
]

# ROOT_URLCONF / WSGI_APPLICATION / ASGI_APPLICATION / SITE_ID
# bleiben im Projekt (backend/settings.py), nicht im Core.


# -------------------------------------------------------------------
# Database
# -------------------------------------------------------------------

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": env("DB_NAME", default="db_build_dummy"),
        "USER": env("DB_USER", default="user_build_dummy"),
        "PASSWORD": env("DB_PASSWORD", default="pass_build_dummy"),
        "HOST": env("DB_HOST", default="db"),
        "PORT": env("DB_PORT", default="5432"),
    }
}

# -------------------------------------------------------------------
# Channels / Redis
# -------------------------------------------------------------------

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [(env("REDIS_HOST", default="redis"), 6379)],
        },
    },
}

PROJECT_NAME = env("PROJECT_NAME", default="Project")


# -------------------------------------------------------------------
# Email
# -------------------------------------------------------------------

EMAIL_BACKEND = (
    "django.core.mail.backends.console.EmailBackend"
    if IS_LOCAL
    else "django.core.mail.backends.smtp.EmailBackend"
)

EMAIL_HOST = env("EMAIL_HOST", default="")
EMAIL_PORT = env("EMAIL_PORT")
EMAIL_USE_TLS = env("EMAIL_USE_TLS")
EMAIL_HOST_USER = env("EMAIL_USER", default="")
EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD", default="")
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

# -------------------------------------------------------------------
# Templates (Projekt setzt DIRS / BASE_DIR)
# -------------------------------------------------------------------

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],  # wird im Projekt gesetzt
        "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",
            ],
        },
    },
]

# -------------------------------------------------------------------
# Static / Media
# -------------------------------------------------------------------

STATIC_URL = "/static/"
MEDIA_URL = "/media/"

STORAGES = {
    "staticfiles": {
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage"
    },
    "default": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
}

# STATIC_ROOT / STATICFILES_DIRS / MEDIA_ROOT hängen von BASE_DIR ab
# und werden im Projekt gesetzt.


# -------------------------------------------------------------------
# Auth / Allauth / REST Framework
# -------------------------------------------------------------------

AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
]

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
    "EXCEPTION_HANDLER": "django_core_micha.auth.exception_handler.custom_exception_handler",
    "DEFAULT_THROTTLE_CLASSES": [
        "rest_framework.throttling.AnonRateThrottle",
        "rest_framework.throttling.UserRateThrottle",
    ],
    "DEFAULT_THROTTLE_RATES": {
        "anon": "100/day",
        "user": "10000/day",
        "sync_client": "1000/minute",
        "password_reset": "50/hour",
        "invite_anon": "30/hour",
        "invite_admin": "500/hour",
        "access_code_validate": "100/hour",
    },
}

SECURITY_LEVELS = ("anon", "recovery", "basic", "strong")

# Per App konfigurierbar (in Projektsettings überschreibbar)
SECURITY_DEFAULT_LEVEL = env("SECURITY_DEFAULT_LEVEL", default="basic")



ACCOUNT_ADAPTER = "django_core_micha.auth.adapters.CoreAccountAdapter"
MFA_ADAPTER = "django_core_micha.auth.adapters.CoreMFAAdapter"
SOCIALACCOUNT_ADAPTER = "django_core_micha.auth.adapters.InvitationOnlySocialAdapter"

ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_LOGIN_METHODS = {'email'}

ACCOUNT_SIGNUP_FIELDS = ['email*']
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = "optional"

LOGIN_REDIRECT_URL = "/"
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"

ACCOUNT_SIGNUP_FIELDS = [
    "email*",
]

MFA_WEBAUTHN_RP_NAME = env("MFA_WEBAUTHN_RP_NAME", default="Project")
MFA_SUPPORTED_TYPES = ["webauthn", "totp", "recovery_codes"]  # optional, falls du später mehr MFA willst

MFA_PASSKEY_LOGIN_ENABLED = True

SOCIALACCOUNT_EMAIL_AUTHENTICATION = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True

SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_EMAIL_REQUIRED = True
SOCIALACCOUNT_LOGIN_ON_GET = True


SOCIALACCOUNT_PROVIDERS = {
    "google": {
        "APP": {
            "client_id": env("GOOGLE_CLIENT_ID", default=""),
            "secret": env("GOOGLE_SECRET", default=""),
            "key": "",
        },
        "SCOPE": ["profile", "email"],
        "AUTH_PARAMS": {"access_type": "online"},
        "EMAIL_AUTHENTICATION": True,
    },
    "microsoft": {
        "APP": {
            "client_id": env("MICROSOFT_CLIENT_ID", default=""),
            "secret": env("MICROSOFT_SECRET", default=""),
            "key": "",
        },
        "SCOPE": ["User.Read"],
        "AUTH_PARAMS": {
            "prompt": "select_account",
        },
    },
}



HEADLESS_ONLY = False
HEADLESS_CLIENTS = ["browser"]
HEADLESS_FRONTEND_URLS = {
    "account_confirm_email": f"{PUBLIC_ORIGIN}/email-verify/{{key}}",
    "account_reset_password": f"{PUBLIC_ORIGIN}/reset-request-password",
    "account_reset_password_from_key": f"{PUBLIC_ORIGIN}/password-reset/{{key}}",
    "account_signup": f"{PUBLIC_ORIGIN}/signup",
    "socialaccount_login_error": f"{PUBLIC_ORIGIN}/login?social=error",
}

MFA_ADAPTER = "allauth.mfa.adapter.DefaultMFAAdapter"
MFA_WEBAUTHN_RP_NAME = env("MFA_WEBAUTHN_RP_NAME", default="Project")

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

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = list(default_headers) + ["X-Admin-Token", "X-CSRFToken"]

LANGUAGE_CODE = "en-us"
TIME_ZONE = "Europe/Zurich"
USE_I18N = True
USE_TZ = True
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# -------------------------------------------------------------------
# Logging
# -------------------------------------------------------------------

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {"class": "logging.StreamHandler"},
    },
    "loggers": {
        "django": {"handlers": ["console"], "level": "INFO"},
        "backend": {  # fest, weil du immer 'backend' nutzt
            "handlers": ["console"],
            "level": "DEBUG" if DEBUG else "INFO",
        },
    },
}
