import logging
from datetime import datetime
from os import getenv, name
from pathlib import Path
from typing import Any

EVIBES_VERSION = "3.1.0"
RELEASE_DATE = datetime(2025, 9, 13)

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

SECRET_KEY = getenv("SECRET_KEY", "SUPER_SECRET_KEY")
DEBUG = bool(int(getenv("DEBUG", "1")))

ALLOWED_HOSTS: set[str] = {
    "app",
    "worker",
    "beat",
    "localhost",
    "api.localhost",
    "b2b.localhost",
    "127.0.0.1",
    "api.127.0.0.1",
    "b2b.127.0.0.1",
}

if DEBUG:
    ALLOWED_HOSTS.add("*")
else:
    for entry in getenv("ALLOWED_HOSTS", "").split(" "):
        ALLOWED_HOSTS.add(entry)

ALLOWED_HOSTS: tuple[str, ...] = tuple(ALLOWED_HOSTS)

CSRF_TRUSTED_ORIGINS: set[str] = {
    "http://127.0.0.1",
    "http://api.localhost",
    "http://b2b.localhost",
}

for entry in getenv("CSRF_TRUSTED_ORIGINS", "").split(" "):
    CSRF_TRUSTED_ORIGINS.add(entry)

CSRF_TRUSTED_ORIGINS: tuple[str, ...] = tuple(CSRF_TRUSTED_ORIGINS)

if DEBUG:
    CORS_ALLOW_ALL_ORIGINS = True
else:
    CORS_ALLOWED_ORIGINS: set[str] = {
        "http://127.0.0.1",
        "http://api.localhost",
        "http://b2b.localhost",
    }
    for entry in getenv("CORS_ALLOWED_ORIGINS", "").split(" "):
        CORS_ALLOWED_ORIGINS.add(entry)

    CORS_ALLOWED_ORIGINS: tuple[str, ...] = tuple(CORS_ALLOWED_ORIGINS)

    CORS_ALLOW_METHODS = (
        "DELETE",
        "GET",
        "OPTIONS",
        "PATCH",
        "POST",
        "PUT",
    )

CORS_ALLOW_HEADERS = (
    "accept",
    "accept-encoding",
    "accept-language",
    "content-type",
    "connection",
    "user-agent",
    "authorization",
    "host",
    "x-csrftoken",
    "x-requested-with",
    "x-evibes-auth",
    "baggage",
    "sentry-trace",
    "dnt",
    "sec-fetch-dest",
    "sec-fetch-mode",
    "sec-fetch-site",
    "sec-gpc",
    "origin",
    "referer",
)

USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") if not DEBUG else None
X_FRAME_OPTIONS = "SAMEORIGIN"

UNSAFE_CACHE_KEYS: list[str] = []

SITE_ID: int = 1

INSTALLED_APPS: list[str] = [
    "django_prometheus",
    "constance",
    "jazzmin",
    "modeltranslation",
    "django.contrib.admin",
    "django.contrib.admindocs",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sitemaps",
    "django.contrib.gis",
    "django.contrib.humanize",
    "health_check",
    "health_check.db",
    "health_check.cache",
    "health_check.storage",
    "health_check.contrib.migrations",
    "health_check.contrib.celery_ping",
    "health_check.contrib.psutil",
    "health_check.contrib.redis",
    "health_check.contrib.db_heartbeat",
    "health_check.contrib.mail",
    "cacheops",
    "django_hosts",
    "django_celery_beat",
    "django_celery_results",
    "django_extensions",
    "django_redis",
    "django_summernote",
    "widget_tweaks",
    "mptt",
    "rest_framework",
    "rest_framework_simplejwt",
    "rest_framework_simplejwt.token_blacklist",
    "drf_spectacular",
    "drf_spectacular_sidecar",
    "django_json_widget",
    "django_elasticsearch_dsl",
    "dbbackup",
    "corsheaders",
    "constance.backends.database",
    "django_mailbox",
    "graphene_django",
    "channels",
    "core",
    "payments",
    "vibes_auth",
    "blog",
]

MIDDLEWARE: list[str] = [
    "evibes.middleware.BlockInvalidHostMiddleware",
    "django_prometheus.middleware.PrometheusBeforeMiddleware",
    "django_hosts.middleware.HostsRequestMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "evibes.middleware.CustomCommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.contrib.admindocs.middleware.XViewMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "evibes.middleware.CustomLocaleMiddleware",
    "django_hosts.middleware.HostsResponseMiddleware",
    "djangorestframework_camel_case.middleware.CamelCaseMiddleWare",
    "django_prometheus.middleware.PrometheusAfterMiddleware",
]

TEMPLATES: list[dict[str, str | list[str | Path] | dict[str, str | list[str]] | Path | bool]] = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            BASE_DIR / "vibes_auth/templates",
            BASE_DIR / "core/templates",
            BASE_DIR / "payments/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",
            ],
        },
    },
]

USE_I18N: bool = True

LANGUAGES: tuple[tuple[str, str], ...] = (
    ("ar-ar", "العربية"),
    ("cs-cz", "Česky"),
    ("da-dk", "Dansk"),
    ("de-de", "Deutsch"),
    ("en-gb", "English (British)"),
    ("en-us", "English (American)"),
    ("es-es", "Español"),
    ("fa-ir", "فارسی"),
    ("fr-fr", "Français"),
    ("he-il", "עברית"),
    ("hi-in", "हिंदी"),
    ("hr-hr", "Hrvatski"),
    ("id-id", "Bahasa Indonesia"),
    ("it-it", "Italiano"),
    ("ja-jp", "日本語"),
    ("kk-kz", "Қазақ"),
    ("ko-kr", "한국어"),
    ("nl-nl", "Nederlands"),
    ("no-no", "Norsk"),
    ("pl-pl", "Polska"),
    ("pt-br", "Português"),
    ("ro-ro", "Română"),
    ("ru-ru", "Русский"),
    ("sv-se", "Svenska"),
    ("th-th", "ไทย"),
    ("tr-tr", "Türkçe"),
    ("vi-vn", "Tiếng Việt"),
    ("zh-hans", "简体中文"),
)

LANGUAGE_CODE: str = "en-gb"

CURRENCIES_BY_LANGUAGES: tuple[tuple[str, str], ...] = (
    ("ar-ar", "AED"),
    ("cs-cz", "CZK"),
    ("da-dk", "DKK"),
    ("de-de", "EUR"),
    ("en-gb", "GBP"),
    ("en-us", "USD"),
    ("es-es", "EUR"),
    ("fa-ir", "IRR"),
    ("fr-fr", "EUR"),
    ("he-il", "ILS"),
    ("hi-in", "INR"),
    ("hr-hr", "EUR"),
    ("id-id", "IDR"),
    ("it-it", "EUR"),
    ("ja-jp", "JPY"),
    ("kk-kz", "KZT"),
    ("ko-kr", "KRW"),
    ("nl-nl", "EUR"),
    ("no-no", "NOK"),
    ("pl-pl", "PLN"),
    ("pt-br", "BRL"),
    ("ro-ro", "RON"),
    ("ru-ru", "RUB"),
    ("sv-se", "SEK"),
    ("th-th", "THB"),
    ("tr-tr", "TRY"),
    ("vi-vn", "VND"),
    ("zh-hans", "CNY"),
)

CURRENCIES_WITH_SYMBOLS: tuple[tuple[str, str], ...] = (
    ("AED", "د.إ"),
    ("BRL", "R$"),
    ("CNY", "¥"),
    ("CZK", "Kč"),
    ("DKK", "kr"),
    ("EUR", "€"),
    ("GBP", "£"),
    ("IDR", "Rp"),
    ("ILS", "₪"),
    ("INR", "₹"),
    ("IRR", "﷼"),
    ("JPY", "¥"),
    ("KRW", "₩"),
    ("KZT", "₸"),
    ("NOK", "kr"),
    ("PLN", "zł"),
    ("RON", "lei"),
    ("RUB", "₽"),
    ("SEK", "kr"),
    ("THB", "฿"),
    ("TRY", "₺"),
    ("USD", "$"),
    ("VND", "₫"),
)

CURRENCY_CODE: str = dict(CURRENCIES_BY_LANGUAGES).get(LANGUAGE_CODE)  # type: ignore[assignment]

MODELTRANSLATION_FALLBACK_LANGUAGES: tuple[str, ...] = (LANGUAGE_CODE, "en-us", "de-de")

ROOT_URLCONF: str = "evibes.urls"

WSGI_APPLICATION: str = "evibes.wsgi.application"

ASGI_APPLICATION: str = "evibes.asgi.application"

DEFAULT_AUTO_FIELD: str = "django.db.models.BigAutoField"

TIME_ZONE: str = getenv("TIME_ZONE", "Europe/London")

STATIC_URL: str = f"https://api.{getenv('EVIBES_BASE_DOMAIN')}/static/"
STATIC_ROOT: Path = BASE_DIR / "static"

MEDIA_URL: str = f"https://api.{getenv('EVIBES_BASE_DOMAIN')}/media/"
MEDIA_ROOT: Path = BASE_DIR / "media"

AUTH_USER_MODEL: str = "vibes_auth.User"

AUTH_PASSWORD_VALIDATORS: list[dict[str, str | int]] = [
    {
        "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",
    },
]

APPEND_SLASH: bool = True

ROOT_HOSTCONF: str = "evibes.hosts"
DEFAULT_HOST: str = "api"
REDIS_PASSWORD: str = getenv("REDIS_PASSWORD", default="")
REDIS_URL: str = f"redis://:{REDIS_PASSWORD}@redis:6379/0"

CHANNEL_LAYERS: dict[str, dict[str, str | dict[str, list[str]]]] = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [getenv("CHANNEL_REDIS_URL", REDIS_URL)],
        },
    },
}

INTERNAL_IPS: list[str] = [
    "127.0.0.1",
]

if getenv("SENTRY_DSN"):
    import sentry_sdk
    from sentry_sdk.integrations.celery import CeleryIntegration
    from sentry_sdk.integrations.django import DjangoIntegration
    from sentry_sdk.integrations.logging import LoggingIntegration
    from sentry_sdk.integrations.redis import RedisIntegration
    from sentry_sdk.types import Event, Hint

    def scrub_sensitive(data: dict[str, Any] | list[Any] | str) -> dict[str, Any] | list[Any] | str | None:
        if isinstance(data, dict):
            cleaned: dict[str, Any] = {}
            for key, value in data.items():
                if key.lower() in ("password", "confirm_password"):
                    cleaned[key] = "[FILTERED]"
                else:
                    cleaned[key] = scrub_sensitive(value)
            return cleaned
        if isinstance(data, list):
            return [scrub_sensitive(item) for item in data]
        return data

    def before_send(event: Event, hint: Hint) -> Event:
        if hint:
            pass
        request = event.get("request", {})
        data = request.get("data", {})
        if data:
            request["data"] = scrub_sensitive(data)  # type: ignore [arg-type]
            event["request"] = request
        return event

    ignore_errors: list[str] = []

    sentry_sdk.init(
        dsn=getenv("SENTRY_DSN"),
        integrations=[
            DjangoIntegration(),
            LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
            CeleryIntegration(),
            RedisIntegration(),
        ],
        environment="development" if DEBUG else "production",
        release=f"evibes@{EVIBES_VERSION}",
        traces_sample_rate=1.0 if DEBUG else 0.2,
        profiles_sample_rate=1.0 if DEBUG else 0.1,
        max_request_body_size="always",
        before_send=before_send,
        ignore_errors=ignore_errors,
        debug=False,
    )

SESSION_COOKIE_HTTPONLY: bool = True
CSRF_COOKIE_HTTPONLY: bool = True
LANGUAGE_COOKIE_HTTPONLY: bool = True

DATA_UPLOAD_MAX_NUMBER_FIELDS: int = 8888

ADMINS: list[tuple[str, ...]] = [("Egor Gorbunov", "contact@fureunoir.com")]

STORAGES: dict[str, dict[str, str | int | bool | None]] = {
    "default": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
    "staticfiles": {
        "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
    },
    "dbbackup": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
}

if name == "nt":
    GDAL_LIBRARY_PATH = r"C:\OSGeo4W\bin\gdal311.dll"
    GEOS_LIBRARY_PATH = r"C:\OSGeo4W\bin\geos_c.dll"
