"""
Django settings for vontor_cz project.

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

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

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""
import os
from typing import Dict, Any
from pathlib import Path

from django.core.management.utils import get_random_secret_key
from django.db import OperationalError, connections

from datetime import timedelta
import json

from celery.schedules import crontab
from dotenv import load_dotenv
load_dotenv()  # Pouze načte proměnné lokálně, pokud nejsou dostupné

# Robust boolean parser and SSL flag
def _env_bool(key: str, default: bool = False) -> bool:
	return os.getenv(key, str(default)).strip().lower() in ("true", "1", "yes", "on")

USE_SSL = _env_bool("SSL", False)

#---------------- ENV VARIABLES USECASE--------------
# v jiné app si to importneš skrz: from django.conf import settings
# a použiješ takto: settings.FRONTEND_URL

FRONTEND_URL = os.getenv("FRONTEND_URL", "http://localhost:9000")
print(f"FRONTEND_URL: {FRONTEND_URL}\n")
#-------------------------BASE ⚙️------------------------

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


# Pavel
# from django.conf.locale.en import formats as en_formats

DATETIME_INPUT_FORMATS = [
    "%Y-%m-%d",              # '2025-07-25'
    "%Y-%m-%d %H:%M",        # '2025-07-25 14:30'
    "%Y-%m-%d %H:%M:%S",     # '2025-07-25 14:30:59'
    "%Y-%m-%dT%H:%M",        # '2025-07-25T14:30'
    "%Y-%m-%dT%H:%M:%S",     # '2025-07-25T14:30:59'
]

# -------------------- LOKALIZACE -------------------------

LANGUAGE_CODE = os.getenv("LANGUAGE_CODE", "cs")
TIME_ZONE = os.getenv("TIME_ZONE", "Europe/Prague")

USE_I18N = True
USE_L10N = True
USE_TZ = True




# SECURITY WARNING: don't run with debug turned on in production!
if os.getenv("DEBUG", "") == "True":
    DEBUG = True
else: 
    DEBUG = False

print(f"\nDEBUG state: {str(DEBUG)}\nDEBUG .env raw: {os.getenv('DEBUG', '')}\n")

#-----------------------BASE END⚙️--------------------------

#--------------- URLS 🌐 -------------------

ASGI_APPLICATION = 'vontor_cz.asgi.application' #daphne
ROOT_URLCONF = 'vontor_cz.urls'
LOGIN_URL = '/admin' #nastavení Login adresy

#-----------------------------------------



#----------------------------------- LOGS -------------------------------------------
#slouží pro tisknutí do konzole v dockeru skrz: logger.debug("content")
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "verbose",
        },
    },
    "formatters": {
        "verbose": {
            "format": "{levelname} {asctime} {name}: {message}",
            "style": "{",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "DEBUG" if DEBUG else "INFO",
    },
}

# -- PŘÍKLAD POUŽITÍ LOGS --
"""
import logging

# Vytvoř si logger podle názvu souboru (modulu)
logger = logging.getLogger(__name__)


logger.debug("Ladicí zpráva – vidíš jen když je DEBUG = True")
logger.info("Informace – např. že uživatel klikl na tlačítko")
logger.warning("Varování – něco nečekaného, ale ne kritického")
logger.error("Chyba – něco se pokazilo, ale aplikace jede dál")
logger.critical("Kritická chyba – selhání systému, třeba pád služby")
"""

# -- SILK -- 
SILKY_PYTHON_PROFILER = True

#---------------------------------- END LOGS ---------------------------------------

#-------------------------------------SECURITY 🔐------------------------------------

if DEBUG:
    SECRET_KEY = 'pernament'
else:
    SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", get_random_secret_key())


SESSION_COOKIE_AGE = 86400  # one day


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

AUTHENTICATION_BACKENDS = [
    #'vontor_cz.backend.EmailOrUsernameModelBackend', #custom backend z authentication aplikace
    'django.contrib.auth.backends.ModelBackend',
]

#--------------------------------END SECURITY 🔐-------------------------------------

#-------------------------------------CORS + HOSTs 🌐🔐------------------------------------

ALLOWED_HOSTS = ["*"]

from urllib.parse import urlparse
parsed = urlparse(FRONTEND_URL)

CSRF_TRUSTED_ORIGINS = [
	f"{parsed.scheme}://{parsed.hostname}:{parsed.port or (443 if parsed.scheme=='https' else 80)}",

	"http://192.168.67.98",
	"https://itsolutions.vontor.cz",
	"https://react.vontor.cz",

	"http://localhost:5173",
	"http://localhost:3000",
	"http://localhost:9000",

	"http://127.0.0.1:5173",
	"http://127.0.0.1:3000",
	"http://127.0.0.1:9000",

	# server
	"http://192.168.67.98",
	"https://itsolutions.vontor.cz",
	"https://react.vontor.cz",

	# nginx docker (local)
	"http://localhost",
	"http://localhost:80",
	"http://127.0.0.1",
]

if DEBUG:
	CORS_ALLOWED_ORIGINS = [
		f"{parsed.scheme}://{parsed.hostname}:{parsed.port or (443 if parsed.scheme=='https' else 80)}",

		"http://localhost:5173",
		"http://localhost:3000",
		"http://127.0.0.1:5173",
		"http://127.0.0.1:3000",
		"http://localhost:9000",
		"http://127.0.0.1:9000",

		# server
		"http://192.168.67.98",
		"https://itsolutions.vontor.cz",
		"https://react.vontor.cz",

		# nginx docker (local)
		"http://localhost",
		"http://localhost:80",
		"http://127.0.0.1",
	]
else:
	CORS_ALLOWED_ORIGINS = [
		"http://192.168.67.98",
		"https://itsolutions.vontor.cz",
		"https://react.vontor.cz",

		"http://localhost:9000",
		"http://127.0.0.1:9000",
	]

CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = False  # Tohle musí být false, když používáš credentials

# Use Lax for http (local), None only when HTTPS is enabled
SESSION_COOKIE_SAMESITE = "None" if USE_SSL else "Lax"
CSRF_COOKIE_SAMESITE = "None" if USE_SSL else "Lax"

print("CORS_ALLOWED_ORIGINS =", CORS_ALLOWED_ORIGINS)
print("CSRF_TRUSTED_ORIGINS =", CSRF_TRUSTED_ORIGINS)
print("ALLOWED_HOSTS =", ALLOWED_HOSTS)

#--------------------------------END CORS + HOSTs 🌐🔐---------------------------------


#--------------------------------------SSL 🧾------------------------------------
if USE_SSL is True:
	print("SSL turned on!")
	SESSION_COOKIE_SECURE = True
	CSRF_COOKIE_SECURE = True
	SECURE_SSL_REDIRECT = True
	SECURE_BROWSER_XSS_FILTER = True
	SECURE_CONTENT_TYPE_NOSNIFF = True
	SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
else:
	SESSION_COOKIE_SECURE = False
	CSRF_COOKIE_SECURE = False
	SECURE_SSL_REDIRECT = False
	SECURE_BROWSER_XSS_FILTER = False
	SECURE_CONTENT_TYPE_NOSNIFF = False
print(f"\nUsing SSL: {USE_SSL}\n")
#--------------------------------END-SSL 🧾---------------------------------





#-------------------------------------REST FRAMEWORK 🛠️------------------------------------

# ⬇️ Základní lifetime konfigurace
ACCESS_TOKEN_LIFETIME = timedelta(minutes=60)
REFRESH_TOKEN_LIFETIME = timedelta(days=5)

# ⬇️ Nastavení SIMPLE_JWT podle režimu
if DEBUG:
	SIMPLE_JWT = {
		"ACCESS_TOKEN_LIFETIME": ACCESS_TOKEN_LIFETIME,
		"REFRESH_TOKEN_LIFETIME": REFRESH_TOKEN_LIFETIME,

		"AUTH_COOKIE": "access_token",
		"AUTH_COOKIE_REFRESH": "refresh_token",

		"AUTH_COOKIE_DOMAIN": None,
		"AUTH_COOKIE_SECURE": False,
		"AUTH_COOKIE_HTTP_ONLY": True,
		"AUTH_COOKIE_PATH": "/",
		"AUTH_COOKIE_SAMESITE": "Lax",

		"ROTATE_REFRESH_TOKENS": False,
		"BLACKLIST_AFTER_ROTATION": False,
	}
else:
	SIMPLE_JWT = {
		"ACCESS_TOKEN_LIFETIME": ACCESS_TOKEN_LIFETIME,
		"REFRESH_TOKEN_LIFETIME": REFRESH_TOKEN_LIFETIME,

		"AUTH_COOKIE": "access_token",
		"AUTH_COOKIE_REFRESH": "refresh_token",
		"AUTH_COOKIE_DOMAIN": None,

		# Secure/SameSite based on HTTPS availability
		"AUTH_COOKIE_SECURE": USE_SSL,
		"AUTH_COOKIE_HTTP_ONLY": True,
		"AUTH_COOKIE_PATH": "/",
		"AUTH_COOKIE_SAMESITE": "None" if USE_SSL else "Lax",

		"ROTATE_REFRESH_TOKENS": True,
		"BLACKLIST_AFTER_ROTATION": True,
	}

REST_FRAMEWORK = {
	"DATETIME_FORMAT": "%Y-%m-%d %H:%M",  # Pavel
	'DEFAULT_AUTHENTICATION_CLASSES': (
		'rest_framework_simplejwt.authentication.JWTAuthentication',
		'account.tokens.CookieJWTAuthentication',
	),
	'DEFAULT_PERMISSION_CLASSES': (
		'rest_framework.permissions.AllowAny',
	),
	'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
	# Default filter backends (ordering, search, filtering)
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.OrderingFilter',
        'rest_framework.filters.SearchFilter',
    ],


    # Enable default pagination so custom list actions (e.g., /orders/detail) paginate
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20,

	'DEFAULT_THROTTLE_RATES': {
		'anon': '100/hour',   # unauthenticated
		'user': '2000/hour',  # authenticated
	},
	
    'EXCEPTION_HANDLER': 'vontor_cz.utils.custom_exception_handler',
    
}
#--------------------------------END REST FRAMEWORK 🛠️-------------------------------------



#-------------------------------------APPS 📦------------------------------------
MY_CREATED_APPS = [
    'account',
    'commerce',
	'configuration',

    'social.chat',
    'social.hubs',
    'social.posts',
	
    'advertisement',
    'notifications',

    'thirdparty.downloader',
    'thirdparty.stripe',  # register Stripe app so its models are recognized
    'thirdparty.trading212',
	'thirdparty.zasilkovna',
    'thirdparty.deutschepost',  # Deutsche Post International Shipping API
    'thirdparty.gopay',  # add GoPay app
]

INSTALLED_APPS = [
    'daphne', #asgi bude fungovat lokálně (musí být na začátku)

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'corsheaders', #cors

    'django_celery_beat', #slouží k plánování úkolů pro Celery

    
    #'chat.apps.GlobalChatCheck', #tohle se spusti při každé django inicializaci (migration, createmigration, runserver)
    
    #'authentication',

    'storages',# Adds support for external storage services like Amazon S3 via django-storages
    'django_filters',

    'channels' ,# django channels

    'rest_framework',
    'rest_framework_api_key',

    'drf_spectacular', #rest framework, grafické zobrazení

    #Nastavení stránky
    #'constance', 
    #'constance.backends.database',
	
    'silk',

    'django.contrib.sitemaps',

    'tinymce',
    

    #kvůli bugum je lepší to dát na poslední místo v INSTALLED_APPS
    'django_cleanup.apps.CleanupConfig', #app která maže nepoužité soubory(media) z databáze na S3
]

#skládaní dohromady INSTALLED_APPS
INSTALLED_APPS = INSTALLED_APPS[:-1] + MY_CREATED_APPS + INSTALLED_APPS[-1:]

# -------------------------------------END APPS 📦------------------------------------





#-------------------------------------MIDDLEWARE 🧩------------------------------------
# Middleware is a framework of hooks into Django's request/response processing.

MIDDLEWARE = [
	"corsheaders.middleware.CorsMiddleware",
	"django.middleware.common.CommonMiddleware",
	'django.middleware.security.SecurityMiddleware',

	'whitenoise.middleware.WhiteNoiseMiddleware',

    'silk.middleware.SilkyMiddleware',

	'django.contrib.sessions.middleware.SessionMiddleware',
	'django.contrib.auth.middleware.AuthenticationMiddleware',
	'django.contrib.messages.middleware.MessageMiddleware',
	'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

#--------------------------------END MIDDLEWARE 🧩---------------------------------





#-------------------------------------CACHE + CHANNELS(ws) 📡🗄️------------------------------------

# Caching settings for Redis (using Docker's internal network name for Redis)
if DEBUG is False:
    #PRODUCTION
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.redis.RedisCache',
            'LOCATION': 'redis://redis:6379/0',  # Using the service name `redis` from Docker Compose
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
                'PASSWORD': os.getenv('REDIS_PASSWORD'),  # Make sure to set REDIS_PASSWORD in your environment
            },
        }
    }

    # WebSockets Channel Layers (using Redis in production)
    CHANNEL_LAYERS = {
        'default': {
            'BACKEND': 'channels_redis.core.RedisChannelLayer',
            'CONFIG': {
                'hosts': [('redis', 6379)],  # Use `redis` service in Docker Compose
            },
        }
    }

else:
    #DEVELOPMENT
    # Use in-memory channel layer for development (when DEBUG is True)
    CHANNEL_LAYERS = {
        'default': {
            'BACKEND': 'channels.layers.InMemoryChannelLayer',
        }
    }

    # Use in-memory cache for development (when DEBUG is True)
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        }
    }

#--------------------------------END CACHE + CHANNELS(ws) 📡🗄️---------------------------------

#-------------------------------------CELERY 📅------------------------------------
CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL")
CELERY_RESULT_BACKEND = os.getenv("CELERY_RESULT_BACKEND")
# Control via env; default False in DEBUG, True otherwise
CELERY_ENABLED = _env_bool("CELERY_ENABLED", default=not DEBUG)

if DEBUG:
	CELERY_ENABLED = False

try:
	import redis
	r = redis.Redis(host='localhost', port=6379, db=0)
	r.ping()
except Exception:
	CELERY_BROKER_URL = 'memory://'
	CELERY_ENABLED = False

def _env_list(key: str, default: list[str]) -> list[str]:
	v = os.getenv(key)
	if not v:
		return default
	try:
		parsed = json.loads(v)
		if isinstance(parsed, (list, tuple)):
			return list(parsed)
		if isinstance(parsed, str):
			return [parsed]
	except Exception:
		pass
	return [s.strip(" '\"") for s in v.strip("[]()").split(",") if s.strip()]

CELERY_ACCEPT_CONTENT = _env_list("CELERY_ACCEPT_CONTENT", ["json"])
CELERY_RESULT_ACCEPT_CONTENT = _env_list("CELERY_RESULT_ACCEPT_CONTENT", ["json"])
CELERY_TASK_SERIALIZER = os.getenv("CELERY_TASK_SERIALIZER", "json")
CELERY_RESULT_SERIALIZER = os.getenv("CELERY_RESULT_SERIALIZER", "json")
CELERY_TIMEZONE = os.getenv("CELERY_TIMEZONE", TIME_ZONE)
CELERY_BEAT_SCHEDULER = os.getenv("CELERY_BEAT_SCHEDULER")

# Celery Beat Schedule for periodic tasks
CELERY_BEAT_SCHEDULE = {
    'send-weekly-new-items-email': {
        'task': 'advertisement.tasks.send_newly_added_items_to_store_email_task_last_week',
        'schedule': crontab(hour=9, minute=0, day_of_week=1),  # Every Monday at 9:00 AM
    },
}
#-------------------------------------END CELERY 📅------------------------------------


#-------------------------------------DATABASE 💾------------------------------------

# Nastavuje výchozí typ primárního klíče pro modely.
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# říka že se úkladá do databáze, místo do cookie
SESSION_ENGINE = 'django.contrib.sessions.backends.db'

USE_DOCKER_DB = os.getenv("USE_DOCKER_DB", "False") in ["True", "true", "1", True]

if USE_DOCKER_DB is False:
	# DEV
	DATABASES = {
		'default': {
			'ENGINE': 'django.db.backends.sqlite3',
			'NAME': BASE_DIR / 'db.sqlite3',
		}
	}
else:
	# DOCKER/POSTGRES
	DATABASES = {
		'default': {
			'ENGINE': os.getenv('DATABASE_ENGINE'),
			'NAME': os.getenv('POSTGRES_DB'),
			'USER': os.getenv('POSTGRES_USER'),
			'PASSWORD': os.getenv('POSTGRES_PASSWORD'),
			'HOST': os.getenv('DATABASE_HOST'),
			'PORT': os.getenv('DATABASE_PORT'),
		}
	}

print(f"\nUsing Docker DB: {USE_DOCKER_DB}\nDatabase settings: {DATABASES}\n")
AUTH_USER_MODEL = 'account.CustomUser' #class CustomUser(AbstractUser) best practice to use AbstractUser

#--------------------------------END DATABASE 💾---------------------------------

#--------------------------------------EMAIL 📧--------------------------------------

EMAIL_BACKEND = os.getenv(
	"EMAIL_BACKEND",
	'django.core.mail.backends.console.EmailBackend' if DEBUG else 'django.core.mail.backends.smtp.EmailBackend'
)

EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = int(os.getenv("EMAIL_PORT", 465))
EMAIL_USE_TLS = os.getenv("EMAIL_USE_TLS", "False") in ["True", "true", "1", True]
EMAIL_USE_SSL = os.getenv("EMAIL_USE_SSL", "True") in ["True", "true", "1", True]
EMAIL_HOST_USER = os.getenv("EMAIL_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_USER_PASSWORD")
DEFAULT_FROM_EMAIL = os.getenv("DEFAULT_FROM_EMAIL", EMAIL_HOST_USER)
EMAIL_TIMEOUT = 30  # seconds

print("---------EMAIL----------")
print("EMAIL_HOST =", EMAIL_HOST)
print("EMAIL_PORT =", EMAIL_PORT)
print("EMAIL_USE_TLS =", EMAIL_USE_TLS)
print("EMAIL_USE_SSL =", EMAIL_USE_SSL)
print("EMAIL_USER =", EMAIL_HOST_USER)
print("------------------------")
#----------------------------------EMAIL END 📧-------------------------------------




#-------------------------------------TEMPLATES 🗂️------------------------------------

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

#--------------------------------END TEMPLATES 🗂️---------------------------------







#-------------------------------------MEDIA + STATIC 🖼️, AWS ☁️------------------------------------

# nastavení složky pro globalstaticfiles (static složky django hledá samo)
STATICFILES_DIRS = [
    BASE_DIR / 'globalstaticfiles',
]



USE_S3 = _env_bool("USE_S3")
print(f"USE_S3: {USE_S3}")

STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'

if not USE_S3:
	# Local filesystem — development only
	STORAGES = {
		"default":     {"BACKEND": "vontor_cz.storage.LocalMediaStorage"},
		"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
	}
	MEDIA_URL  = os.getenv("MEDIA_URL", "/media/")
	MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
	STATIC_URL = '/static/'

else:
	# S3-compatible storage — MinIO (AWS_S3_ENDPOINT_URL set) or real AWS S3 (endpoint empty)
	S3_BUCKET        = os.getenv('AWS_STORAGE_BUCKET_NAME', 'vontor')
	S3_ENDPOINT      = os.getenv('AWS_S3_ENDPOINT_URL', '')
	S3_CUSTOM_DOMAIN = os.getenv('AWS_S3_CUSTOM_DOMAIN', '')
	S3_SSL           = not S3_ENDPOINT or S3_ENDPOINT.startswith('https')
	S3_PROTO         = 'https' if S3_SSL else 'http'

	STORAGES = {
		"default":     {"BACKEND": "vontor_cz.storage.MediaStorage"},
		"staticfiles": {"BACKEND": "vontor_cz.storage.StaticStorage"},
	}

	AWS_ACCESS_KEY_ID        = os.getenv('AWS_ACCESS_KEY_ID')
	AWS_SECRET_ACCESS_KEY    = os.getenv('AWS_SECRET_ACCESS_KEY')
	AWS_STORAGE_BUCKET_NAME  = S3_BUCKET
	AWS_S3_SIGNATURE_VERSION = 's3v4'
	AWS_S3_FILE_OVERWRITE    = False
	AWS_DEFAULT_ACL          = None
	AWS_QUERYSTRING_AUTH     = False
	AWS_S3_USE_SSL           = S3_SSL

	if S3_ENDPOINT:
		# MinIO / S3-compatible: needs path-style addressing
		AWS_S3_ENDPOINT_URL     = S3_ENDPOINT
		AWS_S3_ADDRESSING_STYLE = 'path'
		if S3_CUSTOM_DOMAIN:
			AWS_S3_CUSTOM_DOMAIN = S3_CUSTOM_DOMAIN
			AWS_S3_URL_PROTOCOL  = f'{S3_PROTO}:'
		base_host  = S3_CUSTOM_DOMAIN or f'{S3_ENDPOINT.split("://")[1]}/{S3_BUCKET}'
		MEDIA_URL  = f'{S3_PROTO}://{base_host}/'
		STATIC_URL = f'{S3_PROTO}://{base_host}/static/'
	else:
		# AWS S3
		AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME', 'us-east-1')
		MEDIA_URL  = f'https://{S3_BUCKET}.s3.amazonaws.com/media/'
		STATIC_URL = f'https://{S3_BUCKET}.s3.amazonaws.com/static/'
		CSRF_TRUSTED_ORIGINS.append(STATIC_URL)



print(f"Static url: {STATIC_URL}\nStatic storage: {STORAGES}\n----------------------------")
#--------------------------------END: MEDIA + STATIC 🖼️, AWS ☁️---------------------------------



#-------------------------------------TINY MCE ✍️------------------------------------

TINYMCE_JS_URL = 'https://cdn.tiny.cloud/1/no-api-key/tinymce/7/tinymce.min.js'

TINYMCE_DEFAULT_CONFIG = {
    "height": "320px",
    "width": "960px",
    "menubar": "file edit view insert format tools table help",
    "plugins": "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code "
    "fullscreen insertdatetime media table paste code help wordcount spellchecker",
    "toolbar": "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft "
    "aligncenter alignright alignjustify | outdent indent |  numlist bullist checklist | forecolor "
    "backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | "
    "fullscreen  preview save print | insertfile image media pageembed template link anchor codesample | "
    "a11ycheck ltr rtl | showcomments addcomment code",
    "custom_undo_redo_levels": 10,
}
TINYMCE_SPELLCHECKER = True
TINYMCE_COMPRESSOR = True

#--------------------------------END-TINY-MCE-SECTION ✍️---------------------------------



#-------------------------------------DRF SPECTACULAR 📊------------------------------------

SPECTACULAR_DEFAULTS: Dict[str, Any] = {
    # A regex specifying the common denominator for all operation paths. If
    # SCHEMA_PATH_PREFIX is set to None, drf-spectacular will attempt to estimate
    # a common prefix. Use '' to disable.
    # Mainly used for tag extraction, where paths like '/api/v1/albums' with
    # a SCHEMA_PATH_PREFIX regex '/api/v[0-9]' would yield the tag 'albums'.
    'SCHEMA_PATH_PREFIX': None,

    # Remove matching SCHEMA_PATH_PREFIX from operation path. Usually used in
    # conjunction with appended prefixes in SERVERS.
    'SCHEMA_PATH_PREFIX_TRIM': False,

    # Insert a manual path prefix to the operation path, e.g. '/service/backend'.
    # Use this for example to align paths when the API is mounted as a sub-resource
    # behind a proxy and Django is not aware of that. Alternatively, prefixes can
    # also specified via SERVERS, but this makes the operation path more explicit.
    'SCHEMA_PATH_PREFIX_INSERT': '',

    # Coercion of {pk} to {id} is controlled by SCHEMA_COERCE_PATH_PK. Additionally,
    # some libraries (e.g. drf-nested-routers) use "_pk" suffixed path variables.
    # This setting globally coerces path variables like "{user_pk}" to "{user_id}".
    'SCHEMA_COERCE_PATH_PK_SUFFIX': False,

    # Schema generation parameters to influence how components are constructed.
    # Some schema features might not translate well to your target.
    # Demultiplexing/modifying components might help alleviate those issues.
    'DEFAULT_GENERATOR_CLASS': 'drf_spectacular.generators.SchemaGenerator',

    # Create separate components for PATCH endpoints (without required list)
    'COMPONENT_SPLIT_PATCH': True,

    # Split components into request and response parts where appropriate
    # This setting is highly recommended to achieve the most accurate API
    # description, however it comes at the cost of having more components.
    'COMPONENT_SPLIT_REQUEST': True,

    # Aid client generator targets that have trouble with read-only properties.
    'COMPONENT_NO_READ_ONLY_REQUIRED': False,

    # Adds "minLength: 1" to fields that do not allow blank strings. Deactivated
    # by default because serializers do not strictly enforce this on responses and
    # so "minLength: 1" may not always accurately describe API behavior.
    # Gets implicitly enabled by COMPONENT_SPLIT_REQUEST, because this can be
    # accurately modeled when request and response components are separated.
    'ENFORCE_NON_BLANK_FIELDS': False,

    # This version string will end up the in schema header. The default OpenAPI
    # version is 3.0.3, which is heavily tested. We now also support 3.1.0,
    # which contains the same features and a few mandatory, but minor changes.
    'OAS_VERSION': '3.0.3',

    # Configuration for serving a schema subset with SpectacularAPIView
    'SERVE_URLCONF': None,

    # complete public schema or a subset based on the requesting user
    'SERVE_PUBLIC': True,

    # include schema endpoint into schema
    'SERVE_INCLUDE_SCHEMA': True,

    # list of authentication/permission classes for spectacular's views.
    'SERVE_PERMISSIONS': ['rest_framework.permissions.AllowAny'], #account.permissions.AdminOnly

    # None will default to DRF's AUTHENTICATION_CLASSES
    'SERVE_AUTHENTICATION': None,

    # Dictionary of general configuration to pass to the SwaggerUI({ ... })
    # https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
    # The settings are serialized with json.dumps(). If you need customized JS, use a
    # string instead. The string must then contain valid JS and is passed unchanged.
    'SWAGGER_UI_SETTINGS': {
        'deepLinking': True,
    },

    # Initialize SwaggerUI with additional OAuth2 configuration.
    # https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/
    'SWAGGER_UI_OAUTH2_CONFIG': {},

    # Dictionary of general configuration to pass to the Redoc.init({ ... })
    # https://redocly.com/docs/redoc/config/#functional-settings
    # The settings are serialized with json.dumps(). If you need customized JS, use a
    # string instead. The string must then contain valid JS and is passed unchanged.
    'REDOC_UI_SETTINGS': {},

    # CDNs for swagger and redoc. You can change the version or even host your
    # own depending on your requirements. For self-hosting, have a look at
    # the sidecar option in the README.
    'SWAGGER_UI_DIST': 'https://cdn.jsdelivr.net/npm/swagger-ui-dist@latest',
    'SWAGGER_UI_FAVICON_HREF': 'https://cdn.jsdelivr.net/npm/swagger-ui-dist@latest/favicon-32x32.png',
    'REDOC_DIST': 'https://cdn.jsdelivr.net/npm/redoc@latest',

    # Append OpenAPI objects to path and components in addition to the generated objects
    'APPEND_PATHS': {},
    'APPEND_COMPONENTS': {},


    # Postprocessing functions that run at the end of schema generation.
    # must satisfy interface result = hook(generator, request, public, result)
    'POSTPROCESSING_HOOKS': [
        'drf_spectacular.hooks.postprocess_schema_enums'
    ],

    # Preprocessing functions that run before schema generation.
    # must satisfy interface result = hook(endpoints=result) where result
    # is a list of Tuples (path, path_regex, method, callback).
    # Example: 'drf_spectacular.hooks.preprocess_exclude_path_format'
    'PREPROCESSING_HOOKS': [],

    # Determines how operations should be sorted. If you intend to do sorting with a
    # PREPROCESSING_HOOKS, be sure to disable this setting. If configured, the sorting
    # is applied after the PREPROCESSING_HOOKS. Accepts either
    # True (drf-spectacular's alpha-sorter), False, or a callable for sort's key arg.
    'SORT_OPERATIONS': True,

    # enum name overrides. dict with keys "YourEnum" and their choice values "field.choices"
    # e.g. {'SomeEnum': ['A', 'B'], 'OtherEnum': 'import.path.to.choices'}
    'ENUM_NAME_OVERRIDES': {
        'OrderStatusEnum': 'commerce.models.Order.OrderStatus.choices',
    },

    # Adds "blank" and "null" enum choices where appropriate. disable on client generation issues
    'ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE': True,

    # Add/Append a list of (``choice value`` - choice name) to the enum description string.
    'ENUM_GENERATE_CHOICE_DESCRIPTION': True,

    # Optional suffix for generated enum.
    # e.g. {'ENUM_SUFFIX': "Type"} would produce an enum name 'StatusType'.
    'ENUM_SUFFIX': 'Enum',

    # function that returns a list of all classes that should be excluded from doc string extraction
    'GET_LIB_DOC_EXCLUDES': 'drf_spectacular.plumbing.get_lib_doc_excludes',

    # Function that returns a mocked request for view processing. For CLI usage
    # original_request will be None.
    # interface: request = build_mock_request(method, path, view, original_request, **kwargs)
    'GET_MOCK_REQUEST': 'drf_spectacular.plumbing.build_mock_request',

    # Camelize names like "operationId" and path parameter names
    # Camelization of the operation schema itself requires the addition of
    # 'drf_spectacular.contrib.djangorestframework_camel_case.camelize_serializer_fields'
    # to POSTPROCESSING_HOOKS. Please note that the hook depends on
    # ``djangorestframework_camel_case``, while CAMELIZE_NAMES itself does not.
    'CAMELIZE_NAMES': False,

    # Changes the location of the action/method on the generated OperationId. For example,
    # "POST": "group_person_list", "group_person_create"
    # "PRE":  "list_group_person", "create_group_person"
    'OPERATION_ID_METHOD_POSITION': 'POST',

    # Determines if and how free-form 'additionalProperties' should be emitted in the schema. Some
    # code generator targets are sensitive to this. None disables generic 'additionalProperties'.
    # allowed values are 'dict', 'bool', None
    'GENERIC_ADDITIONAL_PROPERTIES': 'dict',

    # Path converter schema overrides (e.g. <int:foo>). Can be used to either modify default
    # behavior or provide a schema for custom converters registered with register_converter(...).
    # Takes converter labels as keys and either basic python types, OpenApiType, or raw schemas
    # as values. Example: {'aint': OpenApiTypes.INT, 'bint': str, 'cint': {'type': ...}}
    'PATH_CONVERTER_OVERRIDES': {},

    # Determines whether operation parameters should be sorted alphanumerically or just in
    # the order they arrived. Accepts either True, False, or a callable for sort's key arg.
    'SORT_OPERATION_PARAMETERS': True,

    # @extend_schema allows to specify status codes besides 200. This functionality is usually used
    # to describe error responses, which rarely make use of list mechanics. Therefore, we suppress
    # listing (pagination and filtering) on non-2XX status codes by default. Toggle this to enable
    # list responses with ListSerializers/many=True irrespective of the status code.
    'ENABLE_LIST_MECHANICS_ON_NON_2XX': False,

    # This setting allows you to deviate from the default manager by accessing a different model
    # property. We use "objects" by default for compatibility reasons. Using "_default_manager"
    # will likely fix most issues, though you are free to choose any name.
    "DEFAULT_QUERY_MANAGER": 'objects',

    # Controls which authentication methods are exposed in the schema. If not None, will hide
    # authentication classes that are not contained in the whitelist. Use full import paths
    # like ['rest_framework.authentication.TokenAuthentication', ...].
    # Empty list ([]) will hide all authentication methods. The default None will show all.
    'AUTHENTICATION_WHITELIST': None,
    # Controls which parsers are exposed in the schema. Works analog to AUTHENTICATION_WHITELIST.
    # List of allowed parsers or None to allow all.
    'PARSER_WHITELIST': None,
    # Controls which renderers are exposed in the schema. Works analog to AUTHENTICATION_WHITELIST.
    # rest_framework.renderers.BrowsableAPIRenderer is ignored by default if whitelist is None
    'RENDERER_WHITELIST': None,

    # Option for turning off error and warn messages
    'DISABLE_ERRORS_AND_WARNINGS': False,

    # Runs exemplary schema generation and emits warnings as part of "./manage.py check --deploy"
    'ENABLE_DJANGO_DEPLOY_CHECK': True,

    # General schema metadata. Refer to spec for valid inputs
    # https://spec.openapis.org/oas/v3.0.3#openapi-object
    'TITLE': 'e-Tržnice API',
    'DESCRIPTION': 'This is the API documentation for e-Tržnice.',
    'TOS': None,
    # Optional: MAY contain "name", "url", "email"
    'CONTACT': {},
    # Optional: MUST contain "name", MAY contain URL

    'LICENSE': {},
    # Statically set schema version. May also be an empty string. When used together with
    # view versioning, will become '0.0.0 (v2)' for 'v2' versioned requests.
    # Set VERSION to None if only the request version should be rendered.
    'VERSION': '1.0.0',
    # Optional list of servers.
    # Each entry MUST contain "url", MAY contain "description", "variables"
    # e.g. [{'url': 'https://example.com/v1', 'description': 'Text'}, ...]
    'SERVERS': [],
    # Tags defined in the global scope
    'TAGS': [],
    # Optional: List of OpenAPI 3.1 webhooks. Each entry should be an import path to an
    # OpenApiWebhook instance.
    'WEBHOOKS': [],
    # Optional: MUST contain 'url', may contain "description"
    'EXTERNAL_DOCS': {},

    # Arbitrary specification extensions attached to the schema's info object.
    # https://swagger.io/specification/#specification-extensions
    'EXTENSIONS_INFO': {},

    # Arbitrary specification extensions attached to the schema's root object.
    # https://swagger.io/specification/#specification-extensions
    'EXTENSIONS_ROOT': {},

    # Oauth2 related settings. used for example by django-oauth2-toolkit.
    # https://spec.openapis.org/oas/v3.0.3#oauth-flows-object
    'OAUTH2_FLOWS': [],
    'OAUTH2_AUTHORIZATION_URL': None,
    'OAUTH2_TOKEN_URL': None,
    'OAUTH2_REFRESH_URL': None,
    'OAUTH2_SCOPES': None,
}

# --- GoPay configuration (set in backend/.env) ---
GOPAY_GOID = os.getenv("GOPAY_GOID")
GOPAY_CLIENT_ID = os.getenv("GOPAY_CLIENT_ID")
GOPAY_CLIENT_SECRET = os.getenv("GOPAY_CLIENT_SECRET")
GOPAY_GATEWAY_URL = os.getenv("GOPAY_GATEWAY_URL", "https://gw.sandbox.gopay.com/api")
# New: absolute URL that GoPay calls (publicly reachable)
GOPAY_NOTIFICATION_URL = os.getenv("GOPAY_NOTIFICATION_URL", "http://localhost:8000/api/payments/gopay/webhook")

# --- Cloudflare Turnstile ---
CLOUDFLARE_TURNSTILE_SECRET_KEY = os.getenv("SECRET_KEY_TURNSTILE", "")

# -------------------------------------DOWNLOADER LIMITS------------------------------------
DOWNLOADER_MAX_SIZE_MB = int(os.getenv("DOWNLOADER_MAX_SIZE_MB", "200"))  # Raspberry Pi safe cap
DOWNLOADER_MAX_SIZE_BYTES = DOWNLOADER_MAX_SIZE_MB * 1024 * 1024
DOWNLOADER_TIMEOUT = int(os.getenv("DOWNLOADER_TIMEOUT", "120"))  # seconds
DOWNLOADER_TMP_DIR = os.getenv("DOWNLOADER_TMP_DIR", str(BASE_DIR / "tmp" / "downloader"))
# -------------------------------------END DOWNLOADER LIMITS--------------------------------
