import os
from decouple import config
from pathlib import Path
from django.urls import reverse_lazy

BASE_DIR = Path(__file__).resolve().parent.parent

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["assessment.rccgregion29scholarship.org","https://assessment.rccgregion29scholarship.org", "www.assessment.rccgregion29scholarship.org"]

# --- Security ---
SECRET_KEY = config("DJANGO_SECRET_KEY")
SITE_URL = config("SITE_URL", default="https://assessment.rccgregion29scholarship.org")


# SECRET_KEY = config("DJANGO_SECRET_KEY")

# DEBUG = config("DEBUG", default=False, cast=bool)

# ALLOWED_HOSTS = config("ALLOWED_HOSTS", cast=Csv(), default="",)

# CSRF_TRUSTED_ORIGINS = config("CSRF_TRUSTED_ORIGINS", cast=Csv(), default="",)


# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
 
    'maintenance_mode',
    "django_htmx",
    'django_ckeditor_5',
    
    "crispy_forms",
    "crispy_bootstrap5",
    'django_bootstrap5',
    'widget_tweaks',

    # Allauth
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    
    # The MFA app:
    'allauth.mfa',
    # Providers
    "allauth.socialaccount.providers.google",
    "allauth.socialaccount.providers.microsoft",

    'core',
    'cbt',
]


SITE_ID = 1
ALLAUTH_UI_THEME = "dark"

CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"


MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    
    "core.middleware.ForcePasswordChangeMiddleware",
    
    "django.contrib.messages.middleware.MessageMiddleware",
    'allauth.account.middleware.AccountMiddleware',

    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django_htmx.middleware.HtmxMiddleware",
    "maintenance_mode.middleware.MaintenanceModeMiddleware",
]

ROOT_URLCONF = "scholarship.urls"

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",
                "core.context_processors.social_login_config",
            ],
        },
    },
]

WSGI_APPLICATION = "scholarship.wsgi.application"

# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.postgresql',
#         'NAME': config('POSTGRESQl_DB_NAME'),
#         'USER': config('POSTGRESQl_DB_USER'),
#         'PASSWORD': config('POSTGRESQl_DB_PASSWORD', default=''),
#         'HOST': config('POSTGRESQl_DB_HOST'),
#         'PORT': config('POSTGRESQl_DB_PORT', default='5432'),
#     }
# }


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': config('DB_NAME'),
        'USER': config('DB_USER'),
        'PASSWORD': config('DB_PASSWORD', default=''),
        'HOST': config('DB_HOST'),
        'PORT': config('DB_PORT', default='3306'),
    }
}


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 = [
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
]

# 🚦 Rate limits for authentication-related actions
ACCOUNT_RATE_LIMITS = {
    # 🔑 Login attempts
    "login_failed": "5/5m",         # Max 5 failed logins in 5 minutes per IP/user
    # "login_success": "20/1h",       # Optional: Limit total logins per hour

    # 📝 Signup
    "signup": "3/h",                # Max 3 new signups per hour per IP
    "verify_email": "5/h",          # Max 5 verification emails per hour per user

    # 🔄 Password reset
    "password_reset": "3/h",        # Max 3 reset emails per hour
    "password_reset_verify": "5/h",  # Max 5 reset attempts per hour

    # 📧 Email confirmation resend
    "email_confirmation": "3/h",    # Max 3 resends per hour per email

    # (Optional) Social login attempts
    "social_login": "10/1h",        # Max 10 social logins per hour
}

# Redirect URLs
LOGIN_REDIRECT_URL = "/cbt/dashboard/"
LOGOUT_REDIRECT_URL = "/"
ACCOUNT_LOGIN_REDIRECT_URL = "/cbt/dashboard/"
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = "account_login"


# settings.py
ACCOUNT_ADAPTER = "core.adapters.NoSignupAccountAdapter"

ACCOUNT_SIGNUP_REDIRECT_URL = "account_login"
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = False

# Optional account settings
ACCOUNT_LOGIN_METHODS = {"username", "email"}
ACCOUNT_EMAIL_MAX_LENGTH = 255

ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_SIGNUP_FIELDS = ['last_name*', 'first_name*', 'email*', 'username*', 'password1*', 'password2*']
ACCOUNT_EMAIL_VERIFICATION = "mandatory"  # Require confirmation for allauth signup; bulk uploads mark emails verified.
SOCIALACCOUNT_LOGIN_ON_GET = True
SOCIALACCOUNT_AUTO_SIGNUP = True

SOCIALACCOUNT_PROVIDERS = {
    "google": {
        'APP': {
            'client_id': config("GOOGLE_CLIENT_ID"),
            'secret':config("GOOGLE_CLIENT_SECRET"),
            'key': ''
        },
        "SCOPE": ["profile", "email"],
        "AUTH_PARAMS": {"access_type": "online"},
        "OAUTH_PKCE_ENABLED": True,
        
    },
     "microsoft": {
        "APPS": [
            {
                "client_id": "<insert-id>",
                "secret": "<insert-secret>",
                "settings": {
                    "tenant": "organizations",
                    # Optional: override URLs (use base URLs without path)
                    "login_url": "https://login.microsoftonline.com",
                    "graph_url": "https://graph.microsoft.com",
                }
            }
        ]
    }
}

# Email configuration
if DEBUG:
    # Local email backend (development)
    EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
else:
    
    SECURE_HSTS_SECONDS = 31536000  # 1 year
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
    SECURE_HSTS_PRELOAD = True

    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True

    DEBUG = config("DEBUG", default=False, cast=bool)

    # Email settings
    EMAIL_BACKEND = config("EMAIL_BACKEND")
    EMAIL_HOST = config("EMAIL_HOST", default="")
    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="webmaster@localhost")


MFA_ENABLED = True
MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes",]
# Optional: enable support for logging in using a (WebAuthn) passkey.
MFA_PASSKEY_LOGIN_ENABLED = True
# Optional -- use for local development only: the WebAuthn uses the
# ``fido2`` package, and versions up to including version 1.1.3 do not
# regard localhost as a secure origin, which is problematic during
# local development and testing.

if DEBUG:
    MFA_WEBAUTHN_RP_ID = "localhost"
    MFA_WEBAUTHN_ORIGIN = "http://localhost:8000"
    
    MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True
    
    # Avoid forcing cookie domain to "localhost" — this prevents cookies
    # from being set when accessing the site via 127.0.0.1. Leave as None
    # for local development so session and CSRF cookies are stored correctly.
    SESSION_COOKIE_DOMAIN = None
    CSRF_COOKIE_DOMAIN = None

    SESSION_COOKIE_SECURE = False
    CSRF_COOKIE_SECURE = False
    
else:
    MFA_WEBAUTHN_RP_ID = "portal.mysims.com"
    MFA_WEBAUTHN_RP_NAME = "Scholarship Portal"
    MFA_WEBAUTHN_ORIGIN = "https://portal.mysims.com"

MFA_FORMS = {
    'authenticate': 'allauth.mfa.base.forms.AuthenticateForm',
    'reauthenticate': 'allauth.mfa.base.forms.AuthenticateForm',
    'activate_totp': 'allauth.mfa.totp.forms.ActivateTOTPForm',
    'deactivate_totp': 'allauth.mfa.totp.forms.DeactivateTOTPForm',
    'generate_recovery_codes': 'allauth.mfa.recovery_codes.forms.GenerateRecoveryCodesForm',
}


# Maintenance mode
# Turn on/off manually
MAINTENANCE_MODE = False
# Who can bypass maintenance mode
MAINTENANCE_MODE_IGNORE_SUPERUSER = True
# MAINTENANCE_MODE_IGNORE_STAFF = True
# MAINTENANCE_MODE_IGNORE_IP_ADDRESSES = ['127.0.0.1']

# Custom template
MAINTENANCE_MODE_TEMPLATE = 'errors/503.html'


# Internationalization
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True


# Static files (CSS, JavaScript, Images)
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static",]
STATIC_ROOT = BASE_DIR / "staticfiles"

MEDIA_URL = '/media/'  # URL to access media files
MEDIA_ROOT = BASE_DIR / 'media'  # Directory where media files are uploaded

# Default primary key field type
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# CKEditor 5 configurations
customColorPalette = [
    {"color": "hsl(4, 90%, 58%)", "label": "Red"},
    {"color": "hsl(340, 82%, 52%)", "label": "Pink"},
    {"color": "hsl(291, 64%, 42%)", "label": "Purple"},
    {"color": "hsl(262, 52%, 47%)", "label": "Deep Purple"},
    {"color": "hsl(231, 48%, 48%)", "label": "Indigo"},
    {"color": "hsl(207, 90%, 54%)", "label": "Blue"},
]

# CKEDITOR_5_CUSTOM_CSS = 'path_to.css' # optional
# CKEDITOR_5_FILE_STORAGE = "path_to_storage.CustomStorage" # optional
# Define a constant in settings.py to specify file upload permissions
# Possible values: "staff", "authenticated", "any"
CKEDITOR_5_FILE_UPLOAD_PERMISSION = "authenticated"
# CK_EDITOR_5_UPLOAD_FILE_VIEW_NAME = "custom_upload_file"

CKEDITOR_5_CONFIGS = {
    "default": {
        "toolbar": {
            "items": [
                "heading",
                "|",
                "bold",
                "italic",
                "link",
                "bulletedList",
                "numberedList",
                "blockQuote",
                "imageUpload",
                "|",
                "codeBlock",
                "sourceEditing",
                "mediaEmbed",
                "insertImage",
            ],
        }
    },
    "extends": {
        "blockToolbar": [
            "paragraph",
            "heading1",
            "heading2",
            "heading3",
            "|",
            "bulletedList",
            "numberedList",
            "|",
            "blockQuote",
            "insertImage",
        ],
        "toolbar": {
            "items": [
                "heading",
                "|",
                "outdent",
                "indent",
                "|",
                "bold",
                "italic",
                "link",
                "underline",
                "strikethrough",
                "code",
                "subscript",
                "superscript",
                "highlight",
                "|",
                "codeBlock",
                "sourceEditing",
                "insertImage",
                "bulletedList",
                "numberedList",
                "todoList",
                "|",
                "blockQuote",
                "imageUpload",
                "|",
                "fontSize",
                "fontFamily",
                "fontColor",
                "fontBackgroundColor",
                "mediaEmbed",
                "removeFormat",
                "insertTable",
            ],
            "shouldNotGroupWhenFull": "true",
        },
        "image": {
            "toolbar": [
                "imageTextAlternative",
                "|",
                "imageStyle:inline",
                "imageStyle:block",
                "imageStyle:side",
            ],
            "styles": [
                "inline",
                "block",
                "side",
            ],
        },
        "table": {
            "contentToolbar": [
                "tableColumn",
                "tableRow",
                "mergeTableCells",
                "tableProperties",
                "tableCellProperties",
            ],
            "tableProperties": {
                "borderColors": customColorPalette,
                "backgroundColors": customColorPalette,
            },
            "tableCellProperties": {
                "borderColors": customColorPalette,
                "backgroundColors": customColorPalette,
            },
        },
        "heading": {
            "options": [
                {
                    "model": "paragraph",
                    "title": "Paragraph",
                    "class": "ck-heading_paragraph",
                },
                {
                    "model": "heading1",
                    "view": "h1",
                    "title": "Heading 1",
                    "class": "ck-heading_heading1",
                },
                {
                    "model": "heading2",
                    "view": "h2",
                    "title": "Heading 2",
                    "class": "ck-heading_heading2",
                },
                {
                    "model": "heading3",
                    "view": "h3",
                    "title": "Heading 3",
                    "class": "ck-heading_heading3",
                },
            ]
        },
    },
    "list": {
        "properties": {
            "styles": "true",
            "startIndex": "true",
            "reversed": "true",
        }
    },
}



# Logging configuration
LOG_DIR = os.path.join(BASE_DIR, 'logs')

if not os.path.exists(LOG_DIR):
    os.makedirs(LOG_DIR)

# settings.py

import logging


def _set_request_context(record):
    request = getattr(record, 'request', None)
    request_url = 'N/A'
    view_name = 'N/A'
    template_name = getattr(record, 'template_name', 'N/A')

    if request is not None:
        if hasattr(request, 'build_absolute_uri'):
            request_url = request.build_absolute_uri()

        resolver_match = getattr(request, 'resolver_match', None)
        if resolver_match is not None:
            view_name = getattr(resolver_match, 'view_name', 'N/A')

    setattr(record, 'request_url', request_url)
    setattr(record, 'view_name', view_name)
    setattr(record, 'template_name', template_name)
    return True


LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': (
                '[{asctime}] {levelname} '
                'URL: {request_url} | View: {view_name} | Template: {template_name} '
                '- {message}'
            ),
            'style': '{',
        },
    },
    'filters': {
        'request_context': {
            '()': 'django.utils.log.CallbackFilter',
            'callback': _set_request_context,
        },
    },
    'handlers': {
        'file': {
            'level': 'WARNING',  # capture WARNING and ERROR,
            "class": "logging.handlers.TimedRotatingFileHandler",
            'formatter': 'verbose',
            "when": "W6",  # Rotate every 4 weeks on Saturday
            "interval": 4,
            "backupCount": 3,  # Keep last 3 backups
            "encoding": "utf8",
            "filename": os.path.join(LOG_DIR, "django_error.log"),
            'filters': ['request_context'],
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'ERROR',
            'propagate': True,
        },
    },
}

