import logging
import time
import random
from . import BasePlugin

logger = logging.getLogger("nebulascrape.plugins.rate_limit")


class RateLimitPlugin(BasePlugin):
    name = "rate_limit_handler"
    priority = 10

    def __init__(self, min_delay: float = 0.5, max_delay: float = 2.0, burst_threshold: int = 10):
        self._min_delay = min_delay
        self._max_delay = max_delay
        self._burst_threshold = burst_threshold
        self._request_times: list = []

    def _adaptive_delay(self) -> float:
        now = time.monotonic()
        self._request_times = [t for t in self._request_times if now - t < 60]
        count = len(self._request_times)
        if count >= self._burst_threshold:
            return random.uniform(self._max_delay, self._max_delay * 2)
        ratio = count / self._burst_threshold
        return self._min_delay + ratio * (self._max_delay - self._min_delay)

    def on_pre_request(self, scraper, method, url, kwargs):
        delay = self._adaptive_delay()
        if delay > 0.1:
            logger.debug(f"[RateLimitPlugin] Adaptive delay: {delay:.2f}s before {method} {url}")
            time.sleep(delay)
        self._request_times.append(time.monotonic())
        return kwargs

    def on_post_request(self, scraper, response, kwargs):
        if response.status_code == 429:
            ra = response.headers.get("Retry-After")
            if ra:
                try:
                    wait = float(ra) + random.uniform(0.5, 2.0)
                    logger.info(f"[RateLimitPlugin] Retry-After={ra} — sleeping {wait:.1f}s")
                    time.sleep(wait)
                except ValueError:
                    pass
        return response
