"""
Voyage Server settings

Reference:
- Django settings: https://docs.djangoproject.com/en/stable/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from dotenv import load_dotenv
from os import getenv
from pathlib import Path
from urllib.parse import urlparse
from publicsuffix2 import get_sld

# ---------------------------------------------------------------------------
# Environment & Paths
# ---------------------------------------------------------------------------
# Load environment variables from .env file early so getenv works everywhere.
load_dotenv()

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

# Quick-start development settings - unsuitable for production
# See Django deployment checklist for production hardening.

# ---------------------------------------------------------------------------
# Core Security & Debug
# ---------------------------------------------------------------------------
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = getenv("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = getenv("DEBUG", "true").lower() == "true"

# ALLOWED_HOSTS = [
#     'localhost',
#     '127.0.0.1',
#     'server'
# ]
ALLOWED_HOSTS = ["*"]  # In production, restrict to known hosts.

# ---------------------------------------------------------------------------
# Installed Apps
# ---------------------------------------------------------------------------
INSTALLED_APPS = (
    "allauth_ui",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
    "rest_framework",
    "rest_framework.authtoken",
    "allauth",
    "allauth.account",
    "allauth.mfa",
    "allauth.headless",
    "allauth.socialaccount",
    "allauth.socialaccount.providers.github",
    "allauth.socialaccount.providers.openid_connect",
    "invitations",
    "drf_yasg",
    "djmoney",
    "corsheaders",
    "adventures",
    "worldtravel",
    "users",
    "integrations",
    "chat",
    "mcp_server",
    "django.contrib.gis",
    # 'achievements', # Not done yet, will be added later in a future update
    "widget_tweaks",
    "slippers",
)

# ---------------------------------------------------------------------------
# Middleware
# ---------------------------------------------------------------------------
MIDDLEWARE = (
    "whitenoise.middleware.WhiteNoiseMiddleware",
    "adventures.middleware.XSessionTokenMiddleware",
    "adventures.middleware.DisableCSRFForSessionTokenMiddleware",
    "adventures.middleware.DisableCSRFForMobileLoginSignup",
    "corsheaders.middleware.CorsMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "adventures.middleware.OverrideHostMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "allauth.account.middleware.AccountMiddleware",
)

# ---------------------------------------------------------------------------
# Caching
# ---------------------------------------------------------------------------
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
        "LOCATION": "127.0.0.1:11211",
        "TIMEOUT": 60 * 60 * 24,  # Optional: 1 day cache
    }
}

# For backwards compatibility for Django 1.8
MIDDLEWARE_CLASSES = MIDDLEWARE

ROOT_URLCONF = "main.urls"

# WSGI_APPLICATION = 'demo.wsgi.application'

# ---------------------------------------------------------------------------
# Database
# ---------------------------------------------------------------------------
# Using legacy PG environment variables for compatibility with existing setups


def env(*keys, default=None):
    """Return the first non-empty environment variable from a list of keys."""
    for key in keys:
        value = os.getenv(key)
        if value:
            return value
    return default


DATABASES = {
    "default": {
        "ENGINE": "django.contrib.gis.db.backends.postgis",
        "NAME": env("PGDATABASE", "POSTGRES_DB"),
        "USER": env("PGUSER", "POSTGRES_USER"),
        "PASSWORD": env("PGPASSWORD", "POSTGRES_PASSWORD"),
        "HOST": env("PGHOST", default="localhost"),
        "PORT": int(env("PGPORT", default="5432")),
        "OPTIONS": {
            "sslmode": "prefer",  # Prefer SSL, but allow non-SSL connections
        },
    }
}

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

# ---------------------------------------------------------------------------
# Internationalization
# ---------------------------------------------------------------------------
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True

# ---------------------------------------------------------------------------
# Frontend URL & Cookies
# ---------------------------------------------------------------------------
# Derive frontend URL from environment and configure cookie behavior.
unParsedFrontenedUrl = getenv("FRONTEND_URL", "http://localhost:3000")
FRONTEND_URL = unParsedFrontenedUrl.translate(str.maketrans("", "", "'\""))

SESSION_COOKIE_SAMESITE = "Lax"
SESSION_COOKIE_NAME = "sessionid"

# Secure cookies if frontend is served over HTTPS
SESSION_COOKIE_SECURE = FRONTEND_URL.startswith("https")
CSRF_COOKIE_SECURE = FRONTEND_URL.startswith("https")

# Dynamically determine cookie domain to support subdomains while avoiding IPs
hostname = urlparse(FRONTEND_URL).hostname
is_ip_address = hostname.replace(".", "").isdigit()
is_single_label = "." not in hostname  # single-label hostnames (e.g., "localhost")

if is_ip_address or is_single_label:
    SESSION_COOKIE_DOMAIN = None
else:
    cookie_domain = get_sld(hostname)
    SESSION_COOKIE_DOMAIN = f".{cookie_domain}" if cookie_domain else hostname


# ---------------------------------------------------------------------------
# Static & Media Files
# ---------------------------------------------------------------------------
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_ROOT = BASE_DIR / "staticfiles"
STATIC_URL = "/static/"

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"  # Must match NGINX root for media serving
STATICFILES_DIRS = [BASE_DIR / "static"]

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

SILENCED_SYSTEM_CHECKS = ["slippers.E001"]

# ---------------------------------------------------------------------------
# Templates
# ---------------------------------------------------------------------------
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(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",
            ],
        },
    },
]

ALLAUTH_UI_THEME = "dim"

# ---------------------------------------------------------------------------
# Authentication & Accounts
# ---------------------------------------------------------------------------
DISABLE_REGISTRATION = getenv("DISABLE_REGISTRATION", "false").lower() == "true"
DISABLE_REGISTRATION_MESSAGE = getenv(
    "DISABLE_REGISTRATION_MESSAGE",
    "Registration is disabled. Please contact the administrator if you need an account.",
)

SOCIALACCOUNT_ALLOW_SIGNUP = (
    getenv("SOCIALACCOUNT_ALLOW_SIGNUP", "false").lower() == "true"
)

AUTH_USER_MODEL = "users.CustomUser"
ACCOUNT_ADAPTER = "users.adapters.CustomAccountAdapter"
INVITATIONS_ADAPTER = ACCOUNT_ADAPTER
INVITATIONS_ACCEPT_INVITE_AFTER_SIGNUP = True
INVITATIONS_EMAIL_SUBJECT_PREFIX = "Voyage: "
SOCIALACCOUNT_ADAPTER = "users.adapters.CustomSocialAccountAdapter"
ACCOUNT_SIGNUP_FORM_CLASS = "users.form_overrides.CustomSignupForm"

SESSION_SAVE_EVERY_REQUEST = True
LOGIN_REDIRECT_URL = FRONTEND_URL  # Redirect to frontend after login

SOCIALACCOUNT_LOGIN_ON_GET = True
INVITATIONS_INVITE_FORM = "users.form_overrides.UseAdminInviteForm"
INVITATIONS_SIGNUP_REDIRECT_URL = f"{FRONTEND_URL}/signup"

HEADLESS_FRONTEND_URLS = {
    "account_confirm_email": f"{FRONTEND_URL}/user/verify-email/{{key}}",
    "account_reset_password": f"{FRONTEND_URL}/user/reset-password",
    "account_reset_password_from_key": f"{FRONTEND_URL}/user/reset-password/{{key}}",
    "account_signup": f"{FRONTEND_URL}/signup",
    # Fallback if handshake with provider fails and `next` URL is lost.
    "socialaccount_login_error": f"{FRONTEND_URL}/account/provider/callback",
}

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

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_EMAIL_VERIFICATION = getenv(
    "ACCOUNT_EMAIL_VERIFICATION", "none"
)  # 'none', 'optional', 'mandatory'

SOCIALACCOUNT_EMAIL_AUTHENTICATION = True
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True  # Auto-link by email
SOCIALACCOUNT_AUTO_SIGNUP = True  # Allow auto-signup post adapter checks

FORCE_SOCIALACCOUNT_LOGIN = (
    getenv("FORCE_SOCIALACCOUNT_LOGIN", "false").lower() == "true"
)  # When true, only social login is allowed (no password login) and the login page will show only social providers or redirect directly to the first provider if only one is configured.

if getenv("EMAIL_BACKEND", "console") == "console":
    EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
else:
    EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
    EMAIL_HOST = getenv("EMAIL_HOST")
    EMAIL_USE_TLS = getenv("EMAIL_USE_TLS", "true").lower() == "true"
    EMAIL_PORT = getenv("EMAIL_PORT", 587)
    EMAIL_USE_SSL = getenv("EMAIL_USE_SSL", "false").lower() == "true"
    EMAIL_HOST_USER = getenv("EMAIL_HOST_USER")
    EMAIL_HOST_PASSWORD = getenv("EMAIL_HOST_PASSWORD")
    DEFAULT_FROM_EMAIL = getenv("DEFAULT_FROM_EMAIL")

# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_HOST = 'smtp.resend.com'
# EMAIL_USE_TLS = False
# EMAIL_PORT = 2465
# EMAIL_USE_SSL = True
# EMAIL_HOST_USER = 'resend'
# EMAIL_HOST_PASSWORD = ''
# DEFAULT_FROM_EMAIL = 'mail@mail.user.com'


# ---------------------------------------------------------------------------
# Django REST Framework
# ---------------------------------------------------------------------------
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.SessionAuthentication",
    ),
    "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema",
    "DEFAULT_THROTTLE_CLASSES": [
        "rest_framework.throttling.UserRateThrottle",
    ],
    "DEFAULT_THROTTLE_RATES": {
        "user": "1000/day",
        "image_proxy": "60/minute",
    },
}

if DEBUG:
    REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = (
        "rest_framework.renderers.JSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    )
else:
    REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] = (
        "rest_framework.renderers.JSONRenderer",
    )


# ---------------------------------------------------------------------------
# CORS & CSRF
# ---------------------------------------------------------------------------
CORS_ALLOWED_ORIGINS = [
    origin.strip()
    for origin in getenv("CSRF_TRUSTED_ORIGINS", "http://localhost").split(",")
    if origin.strip()
]
CSRF_TRUSTED_ORIGINS = [
    origin.strip()
    for origin in getenv("CSRF_TRUSTED_ORIGINS", "http://localhost").split(",")
    if origin.strip()
]
CORS_ALLOW_CREDENTIALS = True

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
        "file": {
            "class": "logging.FileHandler",
            "filename": "scheduler.log",
        },
    },
    "root": {
        "handlers": ["console", "file"],
        "level": "INFO",
    },
    "loggers": {
        "django": {
            "handlers": ["console", "file"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

# ---------------------------------------------------------------------------
# Public URLs & Third-Party Integrations
# ---------------------------------------------------------------------------
PUBLIC_URL = getenv("PUBLIC_URL", "http://localhost:8000")

# VOYAGE_CDN_URL = getenv('VOYAGE_CDN_URL', 'https://cdn.voyage.app')

# Major release version of Voyage, not including the patch version date.
VOYAGE_RELEASE_VERSION = "v0.12.0"

# https://github.com/dr5hn/countries-states-cities-database/tags
COUNTRY_REGION_JSON_VERSION = "v3.0"

# External service keys (do not hardcode secrets)
GOOGLE_MAPS_API_KEY = getenv("GOOGLE_MAPS_API_KEY", "")
STRAVA_CLIENT_ID = getenv("STRAVA_CLIENT_ID", "")
STRAVA_CLIENT_SECRET = getenv("STRAVA_CLIENT_SECRET", "")
OSRM_BASE_URL = getenv("OSRM_BASE_URL", "https://router.project-osrm.org")

FIELD_ENCRYPTION_KEY = getenv("FIELD_ENCRYPTION_KEY", "")

# Voyage AI Configuration
VOYAGE_AI_PROVIDER = getenv("VOYAGE_AI_PROVIDER", "openai")
VOYAGE_AI_MODEL = getenv("VOYAGE_AI_MODEL", "gpt-4o-mini")
VOYAGE_AI_API_KEY = getenv("VOYAGE_AI_API_KEY", "")

DJANGO_MCP_ENDPOINT = getenv("DJANGO_MCP_ENDPOINT", "api/mcp")
DJANGO_MCP_AUTHENTICATION_CLASSES = [
    "rest_framework.authentication.TokenAuthentication",
]
DJANGO_MCP_ENDPOINT_PERMISSION_CLASSES = [
    "rest_framework.permissions.IsAuthenticated",
]
