import requests


class HttpClient:
    def __init__(self, proxy: str, timeout: int, retry: int):
        self.proxy = proxy
        self.timeout = timeout
        self.retry = retry
        self.proxies = _build_proxies(proxy)
        self.session = requests.Session()

    def get_text(self, url: str, headers: dict | None = None, cookies: dict | None = None) -> str:
        resp = self.get_response(url, headers=headers, cookies=cookies)
        resp.encoding = "utf-8"
        return resp.text

    def get_bytes(self, url: str, headers: dict | None = None, cookies: dict | None = None) -> bytes:
        resp = self.get_response(url, headers=headers, cookies=cookies)
        return resp.content

    def get_response(self, url: str, headers: dict | None = None, cookies: dict | None = None) -> requests.Response:
        return self._request("get", url, headers=headers, cookies=cookies)

    def _request(
        self,
        method: str,
        url: str,
        headers: dict | None = None,
        cookies: dict | None = None,
        data: dict | None = None,
    ) -> requests.Response:
        last_error = None
        for i in range(self.retry):
            try:
                resp = self.session.request(
                    method=method,
                    url=url,
                    timeout=self.timeout,
                    headers=headers,
                    cookies=cookies,
                    data=data,
                    proxies=self.proxies,
                )
                resp.raise_for_status()
                return resp
            except requests.RequestException as err:
                last_error = err
                print(f"[-] Connect retry {i + 1}/{self.retry}: {err}")
        raise RuntimeError(f"Request failed: {method.upper()} {url}") from last_error


def _build_proxies(proxy: str | None) -> dict[str, str] | None:
    if not proxy:
        return None
    proxy_value = proxy.strip()
    if not proxy_value:
        return None
    if "://" not in proxy_value:
        proxy_value = f"http://{proxy_value}"
    return {"http": proxy_value, "https": proxy_value}
