# -*- coding: utf-8 -*-
"""
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/4.2/topics/settings/

For the full list of settings and their values, see:
https://docs.djangoproject.com/en/4.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
# ==============================================================================

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = config('SECRET_KEY', default='django-insecure-change-me-in-production', 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',
    'corsheaders',
    'django_filters',
    'django_extensions',
    'django_celery_beat',
    'django_celery_results',
    # 'crispy_forms',
    # 'crispy_bootstrap5',
    # 'widget_tweaks',
    # 'allauth',
    # 'allauth.account',
    # 'allauth.socialaccount', 
]

# Local applications (Adtlas modules)
LOCAL_APPS = [
    'apps.accounts',  
    # "apps.activities",
    # "apps.authentication", 
    # "apps.agencies",

    # 'apps.campaigns',
    # 'apps.channels',
    # 'apps.advertisers',
    # 'apps.adspots',
    # 'apps.playlists',
    # 'apps.analytics',
    # 'apps.vast',  
    # 'apps.api',   
    # 'apps.creatives',
    # 'apps.epg',
    # 'apps.jingles',
    # 'apps.programs',
    # 'apps.reporting',
    'apps.core',
]

# All installed applications
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

# ==============================================================================
# MIDDLEWARE CONFIGURATION
# ==============================================================================

DJANGO_MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware', # Manages sessions across requests
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware', # Associates users with requests using sessions.
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
] 

LOCAL_MIDDLEWARE = [
    # 'django_session_timeout.middleware.SessionTimeoutMiddleware',
    # '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 + LOCAL_MIDDLEWARE

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

ROOT_URLCONF = 'core.urls'

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

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

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

WSGI_APPLICATION = 'core.wsgi.application'

# ==============================================================================
# DATABASE CONFIGURATION
# ==============================================================================

# Database configuration with support for PostgreSQL and MySQL
import dj_database_url

# Check if DATABASE_URL is provided (Docker environment)
if config('DATABASE_URL', default=None, cast=str):
    DATABASES = {
        'default': dj_database_url.parse(config('DATABASE_URL'))
    }
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),
            'OPTIONS': {
                'charset': 'utf8mb4',
            } if config('DB_ENGINE', default='', cast=str).endswith('mysql') else {},
        }
    }

# Database connection pooling (optional)
if config('DB_CONN_MAX_AGE', default=None):
    DATABASES['default']['CONN_MAX_AGE'] = config('DB_CONN_MAX_AGE', cast=int)
    
# ==============================================================================
# Custom User Model
# ==============================================================================

AUTH_USER_MODEL = 'accounts.User'
 
# ==============================================================================
# PASSWORD VALIDATION
# ==============================================================================

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

# ==============================================================================
# INTERNATIONALIZATION
# ==============================================================================

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"),
)

# ==============================================================================
# STATIC FILES CONFIGURATION
# ==============================================================================

STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
    BASE_DIR / 'static',
]

# ==============================================================================
# MEDIA FILES CONFIGURATION
# ==============================================================================

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

# ==============================================================================
# DEFAULT PRIMARY KEY FIELD TYPE
# ==============================================================================

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

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

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

# ==============================================================================
# SESSION CONFIGURATION
# ==============================================================================

SESSION_EXPIRE_SECONDS = config('SESSION_EXPIRE_SECONDS', default=7200, cast=int)  # 2 hours
SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True
SESSION_TIMEOUT_REDIRECT = '/auth/login/'

# ==============================================================================
# CORS CONFIGURATION
# ==============================================================================

CORS_ALLOWED_ORIGINS = config(
    'CORS_ALLOWED_ORIGINS',
    default='http://localhost:3000,http://127.0.0.1:3000',
    cast=lambda v: [s.strip() for s in v.split(',')]
)
CORS_ALLOW_ALL_ORIGINS = config('CORS_ALLOW_ALL_ORIGINS', default=True, cast=bool)
CORS_ALLOW_CREDENTIALS = True 

# ==============================================================================
# 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,
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

# ==============================================================================
# EMAIL CONFIGURATION
# ==============================================================================

EMAIL_BACKEND = config('EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend', cast=str)
EMAIL_HOST = config('EMAIL_HOST', default='localhost', cast=str)
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='', cast=str)
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='', cast=str)
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool)
DEFAULT_FROM_EMAIL = config('DEFAULT_FROM_EMAIL', default='noreply@adtlas.com', cast=str)

# ==============================================================================
# CELERY CONFIGURATION
# ==============================================================================

CELERY_BROKER_URL = config('CELERY_BROKER_URL', default='redis://localhost:6379/0', cast=str)
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND', default='redis://localhost:6379/0', cast=str)
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = TIME_ZONE 
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

# ==============================================================================
# LOGGING CONFIGURATION
# ==============================================================================

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

# ==============================================================================
# TELEGRAM INTEGRATION
# ==============================================================================

TELEGRAM = {
    'bot_token': config('TELEGRAM_BOT_TOKEN', default='', cast=str),
    'chat_id': config('TELEGRAM_CHAT_ID', default='', cast=str),
    'channel_name': config('TELEGRAM_CHANNEL_NAME', default='adtlas_notifications', cast=str),
}

# ==============================================================================
# FTP CONFIGURATION
# ==============================================================================

FTP_CONFIG = {
    'host': config('FTP_HOST', default='', cast=str),
    'user': config('FTP_USER', default='', cast=str),
    'password': config('FTP_PASSWORD', default='', cast=str),
    'port': config('FTP_PORT', default=21, cast=int),
}

# ==============================================================================
# VAST CONFIGURATION
# ==============================================================================

VAST_CONFIG = {
    'timeout': config('VAST_TIMEOUT', default=30, cast=int),
    'max_workers': config('VAST_MAX_WORKERS', default=100, cast=int),
    'retry_attempts': config('VAST_RETRY_ATTEMPTS', default=3, cast=int),
}

# ==============================================================================
# CUSTOM ADTLAS SETTINGS
# ==============================================================================

# Application URL prefix
APP_URL_PREFIX = config('APP_URL_PREFIX', default='/adtlas/')

# File upload settings 
FILE_UPLOAD_MAX_MEMORY_SIZE = config('FILE_UPLOAD_MAX_MEMORY_SIZE', default=52428800, cast=int)  # 50MB
DATA_UPLOAD_MAX_MEMORY_SIZE = config('DATA_UPLOAD_MAX_MEMORY_SIZE', default=52428800, cast=int)  # 50MB
FILE_UPLOAD_PERMISSIONS = 0o644

ADTLAS_SETTINGS = {
    'MAX_CAMPAIGN_DURATION_DAYS': config('MAX_CAMPAIGN_DURATION_DAYS', default=365, cast=int),
    'DEFAULT_AD_SPOT_DURATION': config('DEFAULT_AD_SPOT_DURATION', default=30, cast=int),
    'MAX_FILE_SIZE_MB': config('MAX_FILE_SIZE_MB', default=500, cast=int),
    'SUPPORTED_VIDEO_FORMATS': ['mp4', 'avi', 'mov', 'wmv', 'flv'],
    'SUPPORTED_AUDIO_FORMATS': ['mp3', 'wav', 'aac', 'ogg'],
    'TELEGRAM_BOT_TOKEN': config('TELEGRAM_BOT_TOKEN', default=''),
    'TELEGRAM_CHAT_ID': config('TELEGRAM_CHAT_ID', default=''),
    'FTP_SETTINGS': {
        'HOST': config('FTP_HOST', default=''),
        'PORT': config('FTP_PORT', default=21, cast=int),
        'USER': config('FTP_USER', default=''),
        'PASSWORD': config('FTP_PASSWORD', default=''),
        'TIMEOUT': config('FTP_TIMEOUT', default=30, cast=int),
    },
    'VAST_SETTINGS': {
        'VERSION': config('VAST_VERSION', default='4.0'),
        'TIMEOUT': config('VAST_TIMEOUT', default=10, cast=int),
        'MAX_REDIRECTS': config('VAST_MAX_REDIRECTS', default=5, cast=int),
    },
    'ANALYTICS_SETTINGS': {
        'RETENTION_DAYS': config('ANALYTICS_RETENTION_DAYS', default=365, cast=int),
        'BATCH_SIZE': config('ANALYTICS_BATCH_SIZE', default=1000, cast=int),
    },
}

# Ad encoding settings
AD_ENCODING_FORMATS = {
    'video': ['mp4', 'avi', 'mov', 'ts'],
    'audio': ['mp3', 'wav', 'aac'],
}

# Campaign settings
CAMPAIGN_DEFAULT_DURATION = config('CAMPAIGN_DEFAULT_DURATION', default=30, cast=int)  # days
CAMPAIGN_MAX_BUDGET = config('CAMPAIGN_MAX_BUDGET', default=1000000.0, cast=float)

# Analytics settings
ANALYTICS_RETENTION_DAYS = config('ANALYTICS_RETENTION_DAYS', default=365, cast=int)
ANALYTICS_BATCH_SIZE = config('ANALYTICS_BATCH_SIZE', default=1000, cast=int)


# ==============================================================================
# RATE LIMITING
# ==============================================================================

RATE_LIMIT_SETTINGS = {
    'DEFAULT_RATE_LIMIT': config('DEFAULT_RATE_LIMIT', default='100/hour'),
    'LOGIN_RATE_LIMIT': config('LOGIN_RATE_LIMIT', default='5/minute'),
    'API_RATE_LIMIT': config('API_RATE_LIMIT', default='1000/hour'),
    'UPLOAD_RATE_LIMIT': config('UPLOAD_RATE_LIMIT', default='10/minute'),
}

# ==============================================================================
# MAINTENANCE MODE
# ==============================================================================

MAINTENANCE_MODE = config('MAINTENANCE_MODE', default=False, cast=bool)
MAINTENANCE_ALLOWED_IPS = config(
    'MAINTENANCE_ALLOWED_IPS',
    default='127.0.0.1,localhost',
    cast=lambda v: [s.strip() for s in v.split(',')]
)

# ==============================================================================
# DEVELOPMENT SETTINGS
# ==============================================================================

if DEBUG:
    INSTALLED_APPS += ['debug_toolbar']
    MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
    INTERNAL_IPS = ['127.0.0.1', 'localhost']
    
    # Debug Toolbar Configuration
    DEBUG_TOOLBAR_CONFIG = {
        'SHOW_TOOLBAR_CALLBACK': lambda request: DEBUG,
    }





# MESSAGE_STORAGE = "django.contrib.messages.storage.session.SessionStorage"

# # ADDITIONAL AND REQUIRED SETTINGS
# AUTH_USER_MODEL = "accounts.Account"

# LOGIN_URL = "auth/login"

# SESSION_COOKIE_AGE = 7200  # Set session expiration to 2 hours (7200 seconds)