import os
from pathlib import Path

from django.core.exceptions import ImproperlyConfigured
from dotenv import dotenv_values, load_dotenv

BASE_DIR = Path(__file__).resolve().parents[2]
load_dotenv(BASE_DIR / ".env", override=False)


def required_env(name, *, local_only=False):
    # The process environment is preferred so a container, service manager or
    # secret manager can supply credentials; the untracked local .env file stays
    # a development convenience. Neither source is trusted more than the other.
    value = os.environ.get(name) or ""
    if not value.strip() and local_only:
        value = dotenv_values(BASE_DIR / ".env", interpolate=False).get(name) or ""
    if not value.strip() or value.strip().lower() in {"replace-me", "changeme"}:
        location = "local .env" if local_only else "local .env or environment"
        raise ImproperlyConfigured(f"Set {name} in your {location}.")
    return value


def env_list(name):
    return [item.strip() for item in os.environ.get(name, "").split(",") if item.strip()]


def env_bool(name, default=False):
    value = os.environ.get(name, str(default)).strip().lower()
    if value not in {"true", "false", "1", "0"}:
        raise ImproperlyConfigured(f"{name} must be True, False, 1, or 0.")
    return value in {"true", "1"}


def env_choice(name, choices, default):
    # Compare case-insensitively but return the declared spelling, because some
    # Django settings validate their value against lowercase constants.
    declared = {str(item).lower(): item for item in choices}
    selected = os.environ.get(name, default).strip().lower()
    if selected not in declared:
        raise ImproperlyConfigured(f"{name} must be one of {', '.join(sorted(str(item) for item in choices))}.")
    return declared[selected]


SECRET_KEY = required_env("DJANGO_SECRET_KEY")
DEBUG = False
ALLOWED_HOSTS = []
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "apps.accounts.apps.AccountsConfig",
    "apps.organization.apps.OrganizationConfig",
    "apps.access.apps.AccessConfig",
    "apps.catalog.apps.CatalogConfig",
    "apps.service_catalog.apps.ServiceCatalogConfig",
    "apps.customers.apps.CustomersConfig",
    "apps.devices.apps.DevicesConfig",
    "apps.service.apps.ServiceConfig",
    "apps.parts.apps.PartsConfig",
    "apps.inventory.apps.InventoryConfig",
    "apps.commercial.apps.CommercialConfig",
    "apps.reporting.apps.ReportingConfig",
    "apps.frontdesk.apps.FrontdeskConfig",
    "apps.communications.apps.CommunicationsConfig",
    "apps.sla.apps.SlaConfig",
    "apps.operations.apps.OperationsConfig",
    "apps.configuration.apps.ConfigurationConfig",
]
MIDDLEWARE = [
    "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",
]
ROOT_URLCONF = "config.urls"
TEMPLATES = [{
    "BACKEND": "django.template.backends.django.DjangoTemplates",
    "DIRS": [BASE_DIR / "templates"],
    "APP_DIRS": True,
    "OPTIONS": {"context_processors": [
        "django.template.context_processors.request",
        "django.contrib.auth.context_processors.auth",
        "django.contrib.messages.context_processors.messages",
        "apps.operations.context.shell",
    ]},
}]
WSGI_APPLICATION = "config.wsgi.application"
ASGI_APPLICATION = "config.asgi.application"
DATABASES = {"default": {
    "ENGINE": "django.db.backends.postgresql",
    "NAME": required_env("DB_NAME"),
    "USER": required_env("DB_USER"),
    "PASSWORD": required_env("DB_PASSWORD", local_only=True),
    "HOST": required_env("DB_HOST"),
    "PORT": required_env("DB_PORT"),
    "OPTIONS": {"connect_timeout": 5},
}}
AUTH_USER_MODEL = "accounts.User"
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"},
]
LANGUAGE_CODE = "en-us"
TIME_ZONE = "Asia/Dhaka"
USE_I18N = True
USE_TZ = True
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# External delivery is opt-in and restricted to production settings.
COMMUNICATIONS_PRODUCTION = False
COMMUNICATIONS_ALLOW_EXTERNAL = env_bool("COMMUNICATIONS_ALLOW_EXTERNAL")
COMMUNICATION_PROVIDERS = {
    channel: os.environ.get(f"COMMUNICATIONS_{channel}_BACKEND", "").strip()
    for channel in ("SMS", "EMAIL")
}
EMAIL_BACKEND = os.environ.get("EMAIL_BACKEND", "django.core.mail.backends.locmem.EmailBackend")
EMAIL_HOST = os.environ.get("EMAIL_HOST", "")
EMAIL_PORT = os.environ.get("EMAIL_PORT", "587")
EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER", "")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD", "")
EMAIL_USE_TLS = env_bool("EMAIL_USE_TLS", default=True)
EMAIL_USE_SSL = env_bool("EMAIL_USE_SSL")
EMAIL_TIMEOUT = 10
DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", "webmaster@localhost")
TEST_RUNNER = "apps.communications.test_runner.NonDeliveringRunner"

# Release identity. Bumped only for a release candidate or release; not per change.
RELEASE_NAME = "C-CARE"
RELEASE_VERSION = "1.0.0-rc2"

# Production logging writes to standard output/stderr only. Destination,
# retention and rotation are the host platform's responsibility; nothing here
# records request bodies, credentials or customer contact values.
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {"plain": {"format": "%(asctime)s %(levelname)s %(name)s %(message)s"}},
    "handlers": {
        "console": {"class": "logging.StreamHandler", "formatter": "plain", "stream": "ext://sys.stdout"},
    },
    "root": {"handlers": ["console"], "level": env_choice("DJANGO_LOG_LEVEL", {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}, "INFO")},
    "loggers": {
        "django": {"handlers": ["console"], "level": "INFO", "propagate": False},
        "django.request": {"handlers": ["console"], "level": "ERROR", "propagate": False},
        "django.security": {"handlers": ["console"], "level": "WARNING", "propagate": False},
        "django.db.backends": {"handlers": ["console"], "level": "WARNING", "propagate": False},
        "apps.communications.delivery": {"handlers": ["console"], "level": "INFO", "propagate": False},
    },
}
