import structlog
from httpx import Client, Response
from typing import Callable, Protocol, Self

log = structlog.get_logger("careful")


class PluginClient(Client):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._plugins = []
        self._raw_request = super().request

    def add_plugin(self, plugin: "Plugin"):
        log.warning("HEY")
        log.debug("adding plugin", plugin=plugin)
        self._plugins.append(plugin)
        plugin._client = self

    def request(self, method, url, **kwargs) -> Response:
        handler = self._raw_request
        # TODO: ?
        for plugin in self._plugins:
            handler = plugin.wrap(handler, self)
        return handler(method, url, **kwargs)


class RequestCallable(Protocol):
    def __call__(self, method: str, url: str, **kwargs) -> Self: ...


class Plugin(Protocol):
    # a callable that takes (~a version of itself~) and returns another
    wrap: Callable[[RequestCallable, PluginClient], RequestCallable]
    _client: PluginClient | None
