import hrequests
from scrapy.http import HtmlResponse
from scrapy.exceptions import NotConfigured
from twisted.internet.threads import deferToThread


class HRequestsDownloadHandler:
    """
    Scrapy download handler powered by hrequests (v0.9.2).

    Features:
    - HTTP/2
    - TLS fingerprinting
    - Proxy support
    - Safe cookie handling
    - Fixes double gzip decoding issue
    """

    def __init__(self, settings, crawler=None):
        if not settings.getbool("HREQUESTS_ENABLED", True):
            raise NotConfigured("HRequests handler disabled")

        self.settings = settings

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.settings, crawler)

    # ----------------------------
    # Blocking hrequests call
    # ----------------------------
    def _blocking_request(self, request):
        proxy = request.meta.get("proxy")

        # Convert Scrapy cookies → plain dict
        cookies = None
        if request.cookies:
            if isinstance(request.cookies, dict):
                cookies = request.cookies
            else:
                try:
                    cookies = {c.name: c.value for c in request.cookies}
                except Exception:
                    cookies = None

        response = hrequests.request(
            method=request.method,
            url=request.url,
            headers=request.headers.to_unicode_dict(),
            data=request.body if request.body else None,
            cookies=cookies,
            proxy=proxy,
            timeout=self.settings.getint("HREQUESTS_TIMEOUT", 30),
            allow_redirects=False,
        )

        return response

    # ----------------------------
    # Scrapy entry point
    # ----------------------------
    def download_request(self, request, spider):
        d = deferToThread(self._blocking_request, request)

        def _build_response(resp):
            # Convert headers to normal dict
            headers = dict(resp.headers)

            # 🔥 Fix: hrequests already decompresses response
            # Remove encoding header to prevent Scrapy double-decompression
            headers.pop("Content-Encoding", None)
            headers.pop("content-encoding", None)

            return HtmlResponse(
                url=str(resp.url),
                status=resp.status_code,
                headers=headers,
                body=resp.content,
                request=request,
                encoding=resp.encoding,
            )

        d.addCallback(_build_response)
        return d
