"""
Django settings for Mnemosyne project.

Environment-variable driven settings for dual-database (PostgreSQL + Neo4j).
Uses django-environ to load from .env file.
"""

import os
from pathlib import Path

import environ

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

# Initialize environment variables
env = environ.Env(
    DEBUG=(bool, True),
)

# Read .env file if it exists
environ.Env.read_env(BASE_DIR / ".env")

# --- Security ---
SECRET_KEY = env("SECRET_KEY", default="django-insecure-change-me-in-production")
DEBUG = env.bool("DEBUG", default=True)
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=["localhost", "127.0.0.1"])
CSRF_TRUSTED_ORIGINS = env.list(
    "CSRF_TRUSTED_ORIGINS", default=["http://localhost:8000"]
)

# Proxy settings — trust X-Forwarded-Proto from HAProxy
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = True

# --- LLM API Encryption ---
LLM_API_SECRETS_ENCRYPTION_KEY = env(
    "LLM_API_SECRETS_ENCRYPTION_KEY", 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.humanize",
    # Third-party
    "rest_framework",
    "storages",
    "django_neomodel",
    "django_prometheus",
    # Mnemosyne apps
    "themis",
    "library",
    "llm_manager",
    "mcp_server",
]

# --- MCP Server ---
MCP_REQUIRE_AUTH = env.bool("MCP_REQUIRE_AUTH", default=True)

MIDDLEWARE = [
    "django_prometheus.middleware.PrometheusBeforeMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "themis.middleware.TimezoneMiddleware",
    "themis.middleware.ThemeMiddleware",
    "django_prometheus.middleware.PrometheusAfterMiddleware",
]

ROOT_URLCONF = "mnemosyne.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "mnemosyne" / "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",
                "themis.context_processors.themis_settings",
                "themis.context_processors.user_preferences",
                "themis.context_processors.notifications",
            ],
        },
    },
]

WSGI_APPLICATION = "mnemosyne.wsgi.application"

# --- Database: PostgreSQL (Django ORM) ---
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": env("APP_DB_NAME", default="mnemosyne"),
        "USER": env("APP_DB_USER", default="mnemosyne"),
        "PASSWORD": env("APP_DB_PASSWORD", default="password"),
        "HOST": env("DB_HOST", default="portia.incus"),
        "PORT": env("DB_PORT", default="5432"),
    }
}

# --- Neo4j Graph Database ---
NEOMODEL_NEO4J_BOLT_URL = env(
    "NEOMODEL_NEO4J_BOLT_URL",
    default="bolt://neo4j:password@ariel.incus:25554",
)

# --- Password validation ---
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",
    },
]

# --- Internationalization ---
LANGUAGE_CODE = env("LANGUAGE_CODE", default="en-us")
TIME_ZONE = env("TIME_ZONE", default="UTC")
USE_I18N = True
USE_TZ = True

# --- Static files ---
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"

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

# --- Storage (S3 or local) ---
USE_LOCAL_STORAGE = env.bool("USE_LOCAL_STORAGE", default=True)

if USE_LOCAL_STORAGE:
    STORAGES = {
        "default": {
            "BACKEND": "django.core.files.storage.FileSystemStorage",
        },
        "staticfiles": {
            "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
        },
    }
else:
    STORAGES = {
        "default": {
            "BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
            "OPTIONS": {
                "access_key": env("AWS_ACCESS_KEY_ID", default=""),
                "secret_key": env("AWS_SECRET_ACCESS_KEY", default=""),
                "bucket_name": env("AWS_STORAGE_BUCKET_NAME", default="mnemosyne-content"),
                "endpoint_url": env("AWS_S3_ENDPOINT_URL", default=""),
                "use_ssl": env.bool("AWS_S3_USE_SSL", default=False),
                "default_acl": "private",
                "region_name": env("AWS_S3_REGION_NAME", default="us-east-1"),
                "file_overwrite": False,
                "querystring_auth": True,
                "verify": env.bool("AWS_S3_VERIFY", default=True),
            },
        },
        "staticfiles": {
            "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
        },
    }

# --- Daedalus S3 (cross-bucket reads for ingest) ---
# Mnemosyne ingests files written to Daedalus's S3 bucket. These vars
# configure read access; the file is copied into AWS_STORAGE_BUCKET_NAME
# (Mnemosyne's own bucket) by the Celery ingest task before processing.
DAEDALUS_S3_ENDPOINT_URL = env("DAEDALUS_S3_ENDPOINT_URL", default="")
DAEDALUS_S3_ACCESS_KEY_ID = env("DAEDALUS_S3_ACCESS_KEY_ID", default="")
DAEDALUS_S3_SECRET_ACCESS_KEY = env("DAEDALUS_S3_SECRET_ACCESS_KEY", default="")
DAEDALUS_S3_BUCKET_NAME = env("DAEDALUS_S3_BUCKET_NAME", default="daedalus")
DAEDALUS_S3_REGION_NAME = env("DAEDALUS_S3_REGION_NAME", default="us-east-1")
DAEDALUS_S3_USE_SSL = env.bool("DAEDALUS_S3_USE_SSL", default=False)
DAEDALUS_S3_VERIFY = env.bool("DAEDALUS_S3_VERIFY", default=True)

# --- Celery / RabbitMQ ---
CELERY_BROKER_URL = env(
    "CELERY_BROKER_URL",
    default="amqp://mnemosyne:password@oberon.incus:5672/mnemosyne",
)
CELERY_RESULT_BACKEND = env("CELERY_RESULT_BACKEND", default="rpc://")
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = TIME_ZONE
CELERY_TASK_ALWAYS_EAGER = env.bool("CELERY_TASK_ALWAYS_EAGER", default=False)
CELERY_TASK_ACKS_LATE = True
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
CELERY_TASK_ROUTES = {
    "library.tasks.embed_*": {"queue": "embedding"},
    "library.tasks.ingest_*": {"queue": "embedding"},
    "library.tasks.batch_*": {"queue": "batch"},
}

# --- Memcached ---
KVDB_LOCATION = env("KVDB_LOCATION", default="127.0.0.1:11211")
KVDB_PREFIX = env("KVDB_PREFIX", default="mnemosyne")

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
        "LOCATION": KVDB_LOCATION,
        "KEY_PREFIX": KVDB_PREFIX,
        "TIMEOUT": 300,
    }
}

# --- Email (smtp4dev on Oberon) ---
EMAIL_HOST = env("EMAIL_HOST", default="oberon.incus")
EMAIL_PORT = env.int("EMAIL_PORT", default=22025)
EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", default=False)
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"

# --- Django REST Framework ---
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
        "rest_framework.authentication.BasicAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    "DEFAULT_PARSER_CLASSES": [
        "rest_framework.parsers.JSONParser",
        "rest_framework.parsers.FormParser",
        "rest_framework.parsers.MultiPartParser",
    ],
    "DEFAULT_RENDERER_CLASSES": [
        "rest_framework.renderers.JSONRenderer",
        "rest_framework.renderers.BrowsableAPIRenderer",
    ],
}

# --- Default primary key field type ---
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# --- Login URLs ---
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"

# --- Embedding Pipeline (Phase 2) ---
EMBEDDING_BATCH_SIZE = env.int("EMBEDDING_BATCH_SIZE", default=8)
EMBEDDING_TIMEOUT = env.int("EMBEDDING_TIMEOUT", default=120)

# --- Search & Re-ranking (Phase 3) ---
SEARCH_VECTOR_TOP_K = env.int("SEARCH_VECTOR_TOP_K", default=50)
SEARCH_FULLTEXT_TOP_K = env.int("SEARCH_FULLTEXT_TOP_K", default=30)
SEARCH_GRAPH_MAX_DEPTH = env.int("SEARCH_GRAPH_MAX_DEPTH", default=2)
SEARCH_RRF_K = env.int("SEARCH_RRF_K", default=60)
SEARCH_DEFAULT_LIMIT = env.int("SEARCH_DEFAULT_LIMIT", default=20)
RERANKER_MAX_CANDIDATES = env.int("RERANKER_MAX_CANDIDATES", default=32)
RERANKER_TIMEOUT = env.int("RERANKER_TIMEOUT", default=30)

# --- Themis app settings ---
THEMIS_APP_NAME = "Mnemosyne"
THEMIS_NOTIFICATION_POLL_INTERVAL = 60
THEMIS_NOTIFICATION_MAX_AGE_DAYS = 90

# --- Structured Logging ---
LOGGING_LEVEL = env("LOGGING_LEVEL", default="INFO")
CELERY_LOGGING_LEVEL = env("CELERY_LOGGING_LEVEL", default="INFO")
DJANGO_LOGGING_LEVEL = env("DJANGO_LOGGING_LEVEL", default="WARNING")

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "structured": {
            "format": (
                "[%(levelname)s] %(asctime)s "
                "service=mnemosyne "
                "module=%(name)s "
                "func=%(funcName)s "
                "line=%(lineno)d "
                "%(message)s"
            ),
            "datefmt": "%Y-%m-%d %H:%M:%S",
        },
        "simple": {
            "format": "[%(levelname)s] %(name)s: %(message)s",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "structured",
            "stream": "ext://sys.stdout",
        },
    },
    "loggers": {
        "library": {
            "handlers": ["console"],
            "level": LOGGING_LEVEL,
            "propagate": False,
        },
        "llm_manager": {
            "handlers": ["console"],
            "level": LOGGING_LEVEL,
            "propagate": False,
        },
        "themis": {
            "handlers": ["console"],
            "level": LOGGING_LEVEL,
            "propagate": False,
        },
        "celery": {
            "handlers": ["console"],
            "level": CELERY_LOGGING_LEVEL,
            "propagate": False,
        },
        "django": {
            "handlers": ["console"],
            "level": DJANGO_LOGGING_LEVEL,
            "propagate": False,
        },
        "django.request": {
            "handlers": ["console"],
            "level": DJANGO_LOGGING_LEVEL,
            "propagate": False,
        },
    },
    "root": {
        "handlers": ["console"],
        "level": LOGGING_LEVEL,
    },
}