from __future__ import annotations

from collections.abc import Callable
from importlib import import_module

from django.conf import settings


DEFAULTS: dict = {
    "MAX_QUERY_LIMIT": 100,
    "DEFAULT_MODEL": "gpt-4",
    "DEFAULT_PROVIDER": "openai",
    "SHOW_INTERNAL": False,
    "SYSTEM_PROMPT_EXTRA": "",
    "EXTRA_TOOLS": [],
    "LOGIN_REQUIRED": False,
}


def get_setting(key: str) -> object:
    """Return a django-anyllm setting, falling back to the default.

    Args:
        key: The setting name (without prefix).

    Returns:
        The configured value or the default.
    """
    user_settings = getattr(settings, "DJANGO_ANYLLM", {})
    return user_settings.get(key, DEFAULTS[key])


def get_extra_tools() -> list[Callable[..., object]]:
    """Return callable tools defined via the ``EXTRA_TOOLS`` setting.

    Each entry in ``EXTRA_TOOLS`` must be a dotted import path string pointing
    to a callable, e.g. ``"myapp.tools.my_custom_tool"``.

    Returns:
        A list of resolved callables, ready to pass to ``any_llm.completion``.

    Raises:
        ImportError: If a module in a dotted path cannot be imported.
        AttributeError: If the attribute does not exist on the resolved module.
    """
    paths: list[str] = get_setting("EXTRA_TOOLS")  # type: ignore[assignment]
    tools: list[Callable[..., object]] = []
    for path in paths:
        module_path, _, attr = path.rpartition(".")
        if not module_path:
            raise ImportError(
                f"EXTRA_TOOLS entry '{path}' must be a dotted path "
                "to a callable (e.g. 'myapp.tools.my_tool')."
            )
        module = import_module(module_path)
        tools.append(getattr(module, attr))
    return tools
