"""Fire-and-forget background execution for slow network I/O (FCM, SMTP).

Production runs WSGI-only on cPanel (no Celery/Redis), so a small daemon
thread pool is the pragmatic way to keep external round-trips off the
request thread. Tasks are best-effort: failures are logged, never raised,
and pending tasks die with the process (acceptable for notifications).

Set BACKGROUND_TASKS_EAGER=True (tests) to run tasks inline.
"""

import logging
from concurrent.futures import ThreadPoolExecutor

from django.conf import settings
from django.db import connections

logger = logging.getLogger(__name__)

_executor = None


def _get_executor():
    global _executor
    if _executor is None:
        workers = getattr(settings, "BACKGROUND_MAX_WORKERS", 4)
        _executor = ThreadPoolExecutor(max_workers=workers, thread_name_prefix="khub-bg")
    return _executor


def run_in_background(fn, *args, **kwargs):
    """Schedule fn(*args, **kwargs) on the background pool. Never raises."""
    if getattr(settings, "BACKGROUND_TASKS_EAGER", False):
        try:
            fn(*args, **kwargs)
        except Exception:
            logger.exception("background task failed (eager): %s", getattr(fn, "__name__", fn))
        return

    def _wrapped():
        try:
            fn(*args, **kwargs)
        except Exception:
            logger.exception("background task failed: %s", getattr(fn, "__name__", fn))
        finally:
            # Worker threads get their own DB connections; close them outright
            # (close_old_connections would keep them open for CONN_MAX_AGE).
            for conn in connections.all(initialized_only=True):
                conn.close()

    try:
        _get_executor().submit(_wrapped)
    except Exception:
        logger.exception("could not submit background task: %s", getattr(fn, "__name__", fn))
