"""Route decorators for common patterns in Flask route handlers."""

import functools

from flask import jsonify, session
from loguru import logger

from ...database.session_context import get_user_db_session
from ...settings import SettingsManager


def with_user_session(include_settings_manager=True):
    """Decorator that provides db_session and optionally SettingsManager.

    Extracts username from session["username"], opens a database session,
    and optionally creates a SettingsManager. Injects them as keyword arguments.

    Requires @login_required to be applied first (outermost) to guarantee
    session["username"] exists. Database session errors are caught and
    returned as 500 JSON responses.

    Args:
        include_settings_manager: If True (default), also inject 'settings_manager'.

    Usage:
        @with_user_session()
        def my_route(db_session, settings_manager):
            ...

        @with_user_session(include_settings_manager=False)
        def my_route(db_session):
            ...
    """

    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            username = session["username"]
            try:
                with get_user_db_session(username) as db_session:
                    kwargs["db_session"] = db_session
                    if include_settings_manager:
                        kwargs["settings_manager"] = SettingsManager(
                            db_session, owns_session=False
                        )
                    return func(*args, **kwargs)
            except Exception:
                logger.exception("Database session error in {}", func.__name__)
                return jsonify({"error": "Database session unavailable"}), 500

        return wrapper

    return decorator
