"""
Django settings for content_manager project.

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

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

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

Inspiration
https://github.com/betagouv/tous-a-bord/blob/main/config/settings.py
"""

import os
import sys
from pathlib import Path

import dj_database_url
from dotenv import load_dotenv

load_dotenv()

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


def getenv_bool(key: str, default: bool):
    try:
        value = os.environ[key]
    except KeyError:
        return default
    return value.casefold() in ["1", "true"]


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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = getenv_bool("DEBUG", False)

ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "127.0.0.1,.localhost").replace(" ", "").split(",")
USE_X_FORWARDED_HOST = getenv_bool("USE_X_FORWARDED_HOST", False)

HOST_PROTO = os.getenv("HOST_PROTO", "https")
HOST_URL = os.getenv("HOST_URL", "localhost")
HOST_PORT = os.getenv("HOST_PORT", "")

# Prefix of the application when served under a sub-path.
# ``FORCE_SCRIPT_NAME`` is the Django setting handling this behaviour:
# https://docs.djangoproject.com/en/5.2/ref/settings/#force-script-name
FORCE_SCRIPT_NAME = os.getenv("FORCE_SCRIPT_NAME", "").rstrip("/")

# Allow enabling WhiteNoise via an environment variable (disabled by default)
SF_USE_WHITENOISE = getenv_bool("SF_USE_WHITENOISE", False)

INTERNAL_IPS = [
    "127.0.0.1",
]

# Applications definition

INSTALLED_APPS = [
    # The order is important for overriding templates and using contexts, please change it carefully.
    "storages",
    "wagtail.contrib.forms",
    "wagtail.contrib.redirects",
    "wagtail.contrib.routable_page",
    "wagtail.contrib.settings",
    "wagtail.contrib.typed_table_block",
    "wagtail.embeds",
    "wagtail.sites",
    "wagtail.users",
    "wagtail.documents",
    "wagtail.images",
    "wagtail.search",
    "wagtail.snippets",
    "wagtail",
    "wagtailmarkdown",
    "wagtailmenus",
    "wagtail_localize",
    "wagtail_localize.locales",
    "taggit",
    "wagtail.api.v2",
    "rest_framework",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.humanize",
    "django.contrib.postgres",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.sitemaps",
    "django.contrib.staticfiles",
    "widget_tweaks",
    "dsfr",
    "content_manager",
    "blog",
    "events",
    "forms",
    "wagtail_honeypot",
    "dashboard",
    "wagtail.admin",
]

if SF_USE_WHITENOISE:
    INSTALLED_APPS.insert(0, "whitenoise.runserver_nostatic")

# Only add these on a dev machine, outside of tests
TESTING = "test" in sys.argv
if not TESTING and DEBUG and "localhost" in HOST_URL:
    INSTALLED_APPS += [
        "wagtail.contrib.styleguide",
        "debug_toolbar",
    ]

# Middleware definition

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "wagtail.contrib.redirects.middleware.RedirectMiddleware",
]

if SF_USE_WHITENOISE:
    MIDDLEWARE.append("whitenoise.middleware.WhiteNoiseMiddleware")

# Only add this on a dev machine, outside of tests
if not TESTING and DEBUG and "localhost" in HOST_URL:
    MIDDLEWARE += [
        "debug_toolbar.middleware.DebugToolbarMiddleware",
    ]

    # Don't show the toolbar on admin previews
    def show_toolbar(request):
        request.META["wsgi.multithread"] = True
        request.META["wsgi.multiprocess"] = True
        excluded_urls = [
            "/pages/preview/",
            "/pages/preview_loading/",
            "/edit/",
            "/edit/preview/",
        ]
        excluded = any(request.path.endswith(url) for url in excluded_urls)
        return not excluded

    DEBUG_TOOLBAR_CONFIG = {
        "SHOW_TOOLBAR_CALLBACK": show_toolbar,
    }

ROOT_URLCONF = "config.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(BASE_DIR, "dsfr/templates"),
            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",
                "wagtail.contrib.settings.context_processors.settings",
                "wagtailmenus.context_processors.wagtailmenus",
                "content_manager.context_processors.skiplinks",
                "content_manager.context_processors.mega_menus",
            ],
        },
    },
]

WSGI_APPLICATION = "config.wsgi.application"
HONEYPOT_ENABLED_DEFAULT = True

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

DATABASE_URL = os.getenv("DATABASE_URL")
if DATABASE_URL:
    DATABASES = {
        "default": dj_database_url.parse(
            DATABASE_URL,
            conn_max_age=600,
            conn_health_checks=True,
        )
    }
else:
    raise ValueError("Please set the DATABASE_URL environment variable")

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

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
        "OPTIONS": {
            "min_length": int(os.getenv("AUTH_PASSWORD_MINIMUM_LENGTH", 15)),
        },
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]

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

LANGUAGE_CODE = "fr"

TIME_ZONE = "Europe/Paris"

USE_I18N = True

USE_TZ = True

WAGTAIL_I18N_ENABLED = True

WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [
    ("en", "English"),
    ("fr", "Français"),
]

LOCALE_PATHS = ["locale"]

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/
STORAGES = {}
STORAGES["staticfiles"] = {
    "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
}

if SF_USE_WHITENOISE:
    if DEBUG:
        STORAGES["staticfiles"] = {
            "BACKEND": "whitenoise.storage.CompressedStaticFilesStorage",
        }
        # Allow WhiteNoise to load files directly from app directories without
        # running ``collectstatic`` each time and reload them on changes.
        WHITENOISE_USE_FINDERS = True
        WHITENOISE_AUTOREFRESH = True
    else:
        STORAGES["staticfiles"] = {
            "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
        }

STATICFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
]

# S3 uploads & MEDIA CONFIGURATION
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html

if os.getenv("S3_HOST"):
    endpoint_url = f"{os.getenv('S3_PROTOCOL', 'https')}://{os.getenv('S3_HOST')}"

    STORAGES["default"] = {
        "BACKEND": "storages.backends.s3.S3Storage",
        "OPTIONS": {
            "bucket_name": os.getenv("S3_BUCKET_NAME", "set-bucket-name"),
            "access_key": os.getenv("S3_KEY_ID", "123"),
            "secret_key": os.getenv("S3_KEY_SECRET", "secret"),
            "endpoint_url": endpoint_url,
            "region_name": os.getenv("S3_BUCKET_REGION", "fr"),
            "file_overwrite": False,
            "location": os.getenv("S3_LOCATION", ""),
        },
    }

    MEDIA_URL = f"{endpoint_url}/"
else:
    STORAGES["default"] = {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    }
    MEDIA_ROOT = os.path.join(BASE_DIR, os.getenv("MEDIA_ROOT", ""))
    MEDIA_URL = os.getenv("MEDIA_URL", "medias/")

    if FORCE_SCRIPT_NAME and not MEDIA_URL.startswith(FORCE_SCRIPT_NAME):
        MEDIA_URL = f"{FORCE_SCRIPT_NAME}/{MEDIA_URL}"

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

STATIC_URL = os.getenv("STATIC_URL", "static/")

if FORCE_SCRIPT_NAME and not STATIC_URL.startswith(FORCE_SCRIPT_NAME):
    STATIC_URL = f"{FORCE_SCRIPT_NAME}/{STATIC_URL}"


# Allow Django to serve statics even in production if needed
SF_PROD_SERVE_STATIC = True if os.getenv("SF_PROD_SERVE_STATIC", False) in ["1", "True"] else False
if SF_PROD_SERVE_STATIC:
    import mimetypes

    mimetypes.add_type("application/javascript", ".js", True)
    mimetypes.add_type("text/css", ".css", True)

    WHITENOISE_STATIC_PREFIX = STATIC_URL

STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)

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

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

# Wagtail settings
# https://docs.wagtail.org/en/stable/reference/settings.html

WAGTAIL_SITE_NAME = os.getenv("SITE_NAME", "Sites Conformes")

# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
WAGTAILADMIN_BASE_URL = os.getenv("WAGTAILADMIN_BASE_URL", "")

# If not set in env, we build it from mandatory variables
if not WAGTAILADMIN_BASE_URL:
    WAGTAILADMIN_BASE_URL = f"{HOST_PROTO}://{HOST_URL}"

    if HOST_PORT:
        WAGTAILADMIN_BASE_URL = f"{WAGTAILADMIN_BASE_URL}:{HOST_PORT}"

WAGTAILAPI_BASE_URL = WAGTAILADMIN_BASE_URL

WAGTAILADMIN_PATH = os.getenv("WAGTAILADMIN_PATH", "cms-admin/")

LOGIN_URL = f"{FORCE_SCRIPT_NAME}/{WAGTAILADMIN_PATH}login/"
LOGOUT_URL = f"{FORCE_SCRIPT_NAME}/{WAGTAILADMIN_PATH}logout/"

WAGTAIL_FRONTEND_LOGIN_URL = LOGIN_URL

WAGTAIL_PASSWORD_REQUIRED_TEMPLATE = "content_manager/password_required.html"

# Disable Gravatar service
WAGTAIL_GRAVATAR_PROVIDER_URL = None

WAGTAIL_RICHTEXT_FIELD_FEATURES = [
    "h2",
    "h3",
    "h4",
    "bold",
    "italic",
    "link",
    "document-link",
    "image",
    "embed",
    "text-left",
    "text-center",
    "text-right",
]

WAGTAILEMBEDS_RESPONSIVE_HTML = True
WAGTAIL_MODERATION_ENABLED = False
WAGTAILMENUS_FLAT_MENUS_HANDLE_CHOICES = (
    ("header_tools", "Menu en haut à droite"),
    ("footer", "Menu en pied de page"),
    ("mega_menu_section_1", "Catégorie de méga-menu 1"),
    ("mega_menu_section_2", "Catégorie de méga-menu 2"),
    ("mega_menu_section_3", "Catégorie de méga-menu 3"),
    ("mega_menu_section_4", "Catégorie de méga-menu 4"),
    ("mega_menu_section_5", "Catégorie de méga-menu 5"),
    ("mega_menu_section_6", "Catégorie de méga-menu 6"),
    ("mega_menu_section_7", "Catégorie de méga-menu 7"),
    ("mega_menu_section_8", "Catégorie de méga-menu 8"),
    ("mega_menu_section_9", "Catégorie de méga-menu 9"),
    ("mega_menu_section_10", "Catégorie de méga-menu 10"),
    ("mega_menu_section_11", "Catégorie de méga-menu 11"),
    ("mega_menu_section_12", "Catégorie de méga-menu 12"),
    ("mega_menu_section_13", "Catégorie de méga-menu 13"),
    ("mega_menu_section_14", "Catégorie de méga-menu 14"),
    ("mega_menu_section_15", "Catégorie de méga-menu 15"),
    ("mega_menu_section_16", "Catégorie de méga-menu 16"),
)

WAGTAILIMAGES_EXTENSIONS = ["gif", "jpg", "jpeg", "png", "webp", "svg"]
SF_SCHEME_DEPENDENT_SVGS = True if os.getenv("SF_SCHEME_DEPENDENT_SVGS", False) in ["1", "True"] else False

# Allows for complex Streamfields without completely removing checks
DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000

# Email settings
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", "")

if DEFAULT_FROM_EMAIL:
    EMAIL_BACKEND = os.getenv("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
    EMAIL_HOST = os.getenv("EMAIL_HOST", None)
    EMAIL_PORT = os.getenv("EMAIL_PORT", None)
    EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER", None)
    EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD", None)
    EMAIL_USE_TLS = os.getenv("EMAIL_USE_TLS", None)
    EMAIL_USE_SSL = os.getenv("EMAIL_USE_SSL", None)
    EMAIL_TIMEOUT = int(os.getenv("EMAIL_TIMEOUT", 30))
    EMAIL_SSL_KEYFILE = os.getenv("EMAIL_SSL_KEYFILE", None)
    EMAIL_SSL_CERTFILE = os.getenv("EMAIL_SSL_CERTFILE", None)

WAGTAIL_PASSWORD_RESET_ENABLED = os.getenv("WAGTAIL_PASSWORD_RESET_ENABLED", False)

# (Optional) ProConnect settings
PROCONNECT_ACTIVATED = True if os.getenv("PROCONNECT_ACTIVATED", False) in ["1", "True"] else False
OIDC_CREATE_USER = True if os.getenv("PROCONNECT_CREATE_USER", "True") in ["1", "True"] else False
OIDC_RP_CLIENT_ID = os.getenv("PROCONNECT_CLIENT_ID", "")
OIDC_RP_CLIENT_SECRET = os.getenv("PROCONNECT_CLIENT_SECRET", "")
OIDC_RP_SCOPES = os.getenv("PROCONNECT_SCOPES", "openid given_name usual_name email siret uid")
OIDC_RP_SIGN_ALGO = os.getenv("PROCONNECT_SIGN_ALGO", "RS256")
OIDC_STORE_ID_TOKEN = True
PROCONNECT_DOMAIN = os.getenv("PROCONNECT_DOMAIN", "fca.integ01.dev-agentconnect.fr")
PROCONNECT_API_ROOT = os.getenv("PROCONNECT_API_ROOT", f"https://{PROCONNECT_DOMAIN}/api/v2")
OIDC_OP_JWKS_ENDPOINT = f"{PROCONNECT_API_ROOT}/jwks"
OIDC_OP_AUTHORIZATION_ENDPOINT = f"{PROCONNECT_API_ROOT}/authorize"
OIDC_OP_TOKEN_ENDPOINT = f"{PROCONNECT_API_ROOT}/token"
OIDC_OP_USER_ENDPOINT = f"{PROCONNECT_API_ROOT}/userinfo"
OIDC_OP_LOGOUT_ENDPOINT = f"{PROCONNECT_API_ROOT}/session/end"
USER_OIDC_ESSENTIAL_CLAIMS = ["email"]
OIDC_AUTH_REQUEST_EXTRA_PARAMS = {"acr_values": "eidas1"}
OIDC_REDIRECT_ALLOWED_HOSTS = ALLOWED_HOSTS
PROCONNECT_USER_CREATION_FILTER = os.getenv("PROCONNECT_USER_CREATION_FILTER", None)
LASUITE_DOMAINE_API_KEY = os.getenv("LASUITE_DOMAINE_API_KEY", None)
SF_DISABLE_LOCAL_LOGIN = True if os.getenv("SF_DISABLE_LOCAL_LOGIN") in ["1", "True"] else False

LOGIN_REDIRECT_URL = f"{FORCE_SCRIPT_NAME}/"
LOGOUT_REDIRECT_URL = f"{FORCE_SCRIPT_NAME}/"

if PROCONNECT_ACTIVATED:
    INSTALLED_APPS += [
        "mozilla_django_oidc",
        "proconnect",
    ]

    AUTHENTICATION_BACKENDS = [
        "django.contrib.auth.backends.ModelBackend",
        "proconnect.backends.OIDCAuthenticationBackend",
    ]

    LOGOUT_URL = f"{FORCE_SCRIPT_NAME}/oidc/logout/"

# CSRF
CSRF_TRUSTED_ORIGINS = []
for host in ALLOWED_HOSTS:
    if host not in ["127.0.0.1", "localhost", ".localhost"]:
        if HOST_PORT:
            CSRF_TRUSTED_ORIGINS.append(f"{HOST_PROTO}://{host}:{HOST_PORT}")
        else:
            CSRF_TRUSTED_ORIGINS.append(f"{HOST_PROTO}://{host}")

trusted_origins = os.getenv("CSRF_TRUSTED_ORIGINS", "").replace(" ", "").split(",")
trusted_origins = list(filter(None, trusted_origins))

if len(trusted_origins):
    CSRF_TRUSTED_ORIGINS += trusted_origins

# Disable the integrity checksums by default.
# They can clash with Whitenoise and are normally not useful as we serve the statics from a trusted source
DSFR_USE_INTEGRITY_CHECKSUMS = True if os.getenv("DSFR_USE_INTEGRITY_CHECKSUMS") in ["1", "True"] else False

SF_DISABLE_TUTORIALS = True if os.getenv("SF_DISABLE_TUTORIALS") in ["1", "True"] else False
SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
