"""
Django settings for Adtlas DAI Management System.

This file contains all the configuration settings for the Adtlas project.
The project is designed for Dynamic Ad Insertion (DAI) management in broadcast television.

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/
"""

from pathlib import Path
from decouple import Csv, config
from django.utils.translation import gettext_lazy as _

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


# ==============================================================================
# CORE SETTINGS
# ==============================================================================
# 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 = config("SECRET_KEY", default="django-insecure-x+fk6m*$@q4c+3g5ta*$89_stqgegxxlmt42fe5pt$wb)m11-h", cast=str)

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = config("DEBUG", default=True, cast=bool)

# Allowed hosts for the application
ALLOWED_HOSTS = config("ALLOWED_HOSTS", default="127.0.0.1,localhost", cast=Csv())


# ==============================================================================
# APPLICATION DEFINITION
# ==============================================================================

# Django built-in applications
DJANGO_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",           # Core authentication framework and its default models.
    "django.contrib.contenttypes",   # Django content type system (allows permissions to be associated with models).
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
]

# Third-party applications
THIRD_PARTY_APPS = [
    "rest_framework",
    "rest_framework.authtoken",
    "rest_framework_simplejwt",
    "corsheaders",
    "django_filters",
    "django_extensions",
    "django_celery_beat",
    "django_prometheus",
]

# Local applications (Adtlas modules)
LOCAL_APPS = [
    "apps.core",
    "apps.accounts",
    "apps.activities",
    "apps.agencies",
    "apps.authentication",
    "apps.campaigns",
    "apps.channels",
    "apps.notifications",
    "apps.playlists",
    "apps.reports",
    "apps.vast",
]
 
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS


# ==============================================================================
# MIDDLEWARE SETTINGS
# ==============================================================================

# All installed applications
DJANGO_MIDDLEWARE = [
    "django_prometheus.middleware.PrometheusBeforeMiddleware",
    "corsheaders.middleware.CorsMiddleware", # CORS middleware (should be as high as possible)
    "django.middleware.security.SecurityMiddleware", # Security middleware
    "django.contrib.sessions.middleware.SessionMiddleware", # Manages sessions across requests
    "django.middleware.common.CommonMiddleware", # Common middleware
    "django.middleware.csrf.CsrfViewMiddleware", # CSRF protection middleware
    "django.contrib.auth.middleware.AuthenticationMiddleware", # Associates users with requests using sessions.
    "django.contrib.messages.middleware.MessageMiddleware", # Messages middleware
    "django.middleware.clickjacking.XFrameOptionsMiddleware", # Clickjacking protection middleware
    "django_prometheus.middleware.PrometheusAfterMiddleware",
]

THIRD_PARTY_MIDDLEWARE = [
    "django_session_timeout.middleware.SessionTimeoutMiddleware",
]


LOCAL_MIDDLEWARE = [ 
    # "apps.core.middleware.RequestMiddleware",       
    # "apps.accounts.middleware.UserActivityMiddleware",
    # "apps.accounts.middleware.RateLimitMiddleware",
    # "apps.accounts.middleware.SecurityHeadersMiddleware",
    # "apps.accounts.middleware.MaintenanceModeMiddleware",
    # "apps.accounts.middleware.RequestLoggingMiddleware",
]

MIDDLEWARE = DJANGO_MIDDLEWARE + THIRD_PARTY_MIDDLEWARE + LOCAL_MIDDLEWARE


# ==============================================================================
# URL CONFIGURATION
# ==============================================================================

ROOT_URLCONF = "core.urls"


# ==============================================================================
# TEMPLATE CONFIGURATION
# ==============================================================================

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"], # Global templates directory
        "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",
                "django.template.context_processors.media",
                "django.template.context_processors.static",
            ],
        },
    },
]


# ==============================================================================
# WSGI CONFIGURATION
# ==============================================================================

WSGI_APPLICATION = "core.wsgi.application"


# ==============================================================================
# DATABASE CONFIGURATION
# ==============================================================================
# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
# Database configuration with support for PostgreSQL and MySQL
# Check if DATABASE_URL is provided (Docker environment)
if config("DATABASE_URL", default="", cast=str):
    import dj_database_url
    DATABASES = {
        "default": dj_database_url.parse(config("DATABASE_URL", default="", cast=str))
    }
else:
    DATABASES = {
        "default": {
            "ENGINE": config("DB_ENGINE", default="django.db.backends.sqlite3", cast=str),
            "NAME": config("DB_NAME", default=BASE_DIR / "db.sqlite3", cast=str),
            "USER": config("DB_USER", default="", cast=str),
            "PASSWORD": config("DB_PASSWORD", default="", cast=str),
            "HOST": config("DB_HOST", default="", cast=str),
            "PORT": config("DB_PORT", default="", cast=str),
            "CONN_MAX_AGE": config("DB_CONN_MAX_AGE", default=60, cast=int),
            "OPTIONS": { 
                "charset": "utf8mb4",
            } if config("DB_ENGINE", default="", cast=str).endswith("mysql") else { }, 
            "TEST": {
                "NAME": "test_adtlas_db",
            }
        }
    }


# ==============================================================================
# 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": 8,
        }
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]


# ==============================================================================
# STATIC FILES CONFIGURATION
# ==============================================================================
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles" # For production
STATICFILES_DIRS = [
    BASE_DIR / "static",  # Global static files directory
]
# STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"


# ==============================================================================
# MEDIA FILES CONFIGURATION
# ==============================================================================
# Media files (User uploaded files)

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"


# ==============================================================================
# DEFAULT PRIMARY KEY FIELD TYPE
# ==============================================================================
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"


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

LANGUAGE_CODE = config("LANGUAGE_CODE", default="en-us", cast=str)
TIME_ZONE = config("TIME_ZONE", default="UTC", cast=str)
USE_I18N = True
USE_L10N = True
USE_TZ = True
USE_THOUSAND_SEPARATOR = True
 
LANGUAGES = [
    ("ar", _("Arabic")),
    ("en", _("English")),
    ("fr", _("French")),
]

LOCALE_PATHS = (
    (BASE_DIR / "locale"),
)


# ==============================================================================
# Site ID for django.contrib.sites
# ==============================================================================

SITE_ID = config("SITE_ID", default=1, cast=int) 


# ==============================================================================
# Custom User Model
# ==============================================================================

AUTH_USER_MODEL = "accounts.User"

# Authentication Settings
LOGIN_URL = "auth:login"
LOGIN_REDIRECT_URL = "core:dashboard" 


# ==============================================================================
# CSRF CONFIGURATION
# ==============================================================================

# CSRF trusted origins for cross-origin requests (configured in security section below) 

# Cookie security
SESSION_COOKIE_SECURE = config("SESSION_COOKIE_SECURE", default=True, cast=bool)
CSRF_COOKIE_SECURE = config("CSRF_COOKIE_SECURE", default=True, cast=bool)
SESSION_COOKIE_HTTPONLY = config("SESSION_COOKIE_HTTPONLY", default=True, cast=bool)
CSRF_COOKIE_HTTPONLY = config("CSRF_COOKIE_HTTPONLY", default=False, cast=bool)  # Allow JavaScript access if needed
SESSION_COOKIE_SAMESITE = config("SESSION_COOKIE_SAMESITE", default="Lax")
CSRF_COOKIE_SAMESITE = config("CSRF_COOKIE_SAMESITE", default="Lax")

# Additional CSRF settings for reverse proxy
CSRF_USE_SESSIONS = False
CSRF_TRUSTED_ORIGINS = config(
    "CSRF_TRUSTED_ORIGINS",
    default="https://localhost:8000,https://127.0.0.1:8000",
    cast=Csv()
)


# ==============================================================================
# CORS Configuration
# ==============================================================================

CORS_ORIGIN_ALLOW_ALL = config("CORS_ORIGIN_ALLOW_ALL", default=False, cast=bool)
CORS_ALLOW_CREDENTIALS = True
 
# CORS Configuration
CORS_ALLOWED_ORIGINS = config(
    "CORS_ALLOWED_ORIGINS",
    default="http://localhost:3000,http://127.0.0.1:3000",
    cast=Csv()
)

# ==============================================================================
# Redis Configuration
# ==============================================================================

REDIS_URL = config("REDIS_URL", default="redis://localhost:6379/0")


# ==============================================================================
# Cache Configuration
# ==============================================================================

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": REDIS_URL,
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}


# ==============================================================================
# Session Configuration
# ==============================================================================

SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
SESSION_COOKIE_AGE = 86400  # 24 hours


# ==============================================================================
# Celery Configuration
# ==============================================================================

CELERY_BROKER_URL = REDIS_URL
CELERY_RESULT_BACKEND = config("CELERY_RESULT_BACKEND", default=REDIS_URL)
CELERY_CACHE_BACKEND = "django-cache"
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = TIME_ZONE
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"


# ==============================================================================
# Email Configuration
# ==============================================================================

EMAIL_BACKEND = config("EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend")
EMAIL_HOST = config("EMAIL_HOST", default="localhost")
EMAIL_PORT = config("EMAIL_PORT", default=587, cast=int)
EMAIL_USE_TLS = config("EMAIL_USE_TLS", default=True, cast=bool)
EMAIL_HOST_USER = config("EMAIL_HOST_USER", default="")
EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD", default="")
DEFAULT_FROM_EMAIL = config("DEFAULT_FROM_EMAIL", default="noreply@adtlas.tv")


# ==============================================================================
# REST Framework Configuration
# ==============================================================================

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.TokenAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 20,
}


 #


 

# ==============================================================================
 

 

TELEGRAM = {
    'bot_token': config('TELEGRAM_BOT_TOKEN', default=''),
    'channel_name': config('TELEGRAM_CHANNEL_NAME', default=''),
}
  
XMLFILES_URL = '/media/'
XMLFILES_DIRS = [
    (BASE_DIR, "media"),
]

appurl = "/DAIManagement/"
 
SESSION_EXPIRE_SECONDS = 1800  # 30 min 
SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True 
SESSION_TIMEOUT_REDIRECT = "auth:logout"


 
# APPEND_SLASH=False
# ==============================================================================
# LOGGING CONFIGURATION
# ==============================================================================
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '[{levelname}] {asctime} {name} {process:d} {thread:d} {message}',
            'style': '{',
        },
        'simple': {
            'format': '[{levelname}] {asctime} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': BASE_DIR / 'logs' / 'django.log',
            'formatter': 'verbose',
        },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
        },
        'celery_file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': BASE_DIR / 'logs' / 'celery.log',
            'formatter': 'verbose',
        },
    },
    'root': {
        'handlers': ['console', 'file'],
        'level': 'INFO',
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'console'],
            'level': 'INFO',
            'propagate': True,
        },
        'apps': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
            'propagate': False,
        },
        'apps.vast': {
            'handlers': ['file', 'console'],
            'level': 'INFO',
            'propagate': True,
        },
        'celery': {
            'handlers': ['celery_file', 'console'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}

# Create logs directory if it doesn't exist
import os
logs_dir = BASE_DIR / 'logs'
if not os.path.exists(logs_dir):
    os.makedirs(logs_dir)
