from __future__ import annotations
import time
from typing import Any, Dict, Optional, Union
import requests


def GET_直到成功(
    url: str,
    params: Optional[Dict[str, Any]] = None,
    headers: Optional[Dict[str, str]] = None,
    cookies: Optional[Dict[str, str]] = None,
    timeout: Union[int, float] = 10,
    allow_redirects: bool = True,
    verify: bool = True,
    proxies: Optional[Dict[str, str]] = None,
    重试间隔秒: Union[int, float] = 3,
    最大尝试次数: Optional[int] = None,
) -> Optional[requests.Response]:
    """
    持续发送 HTTP GET 请求，直到请求成功或达到最大尝试次数。

    本函数为完全独立实现：
        - 不调用任何其他 HTTP 工具函数
        - 内部自行处理请求、状态码判断与重试逻辑
        - 不抛出异常，适合爬虫与自动化场景

    成功判定规则：
        - HTTP 状态码在 200 ~ 299 范围内视为成功

    Args:
        url (str): 目标 URL，例如 "https://example.com/api".
        params (Optional[Dict[str, Any]]): Query 参数字典，会自动拼接到 URL 上。
        headers (Optional[Dict[str, str]]): 请求头字典，例如 {"User-Agent": "..."}。
        cookies (Optional[Dict[str, str]]): Cookie 字典。
        timeout (Union[int, float]): 超时时间（秒），例如 10 或 3.5。
        allow_redirects (bool): 是否允许自动跟随重定向。
        verify (bool): 是否验证 HTTPS 证书。为 False 时可能降低安全性。
        proxies (Optional[Dict[str, str]]): 代理配置，例如：
            {"http": "http://127.0.0.1:7890", "https": "http://127.0.0.1:7890"}。
        重试间隔秒 (Union[int, float]): 每次失败后的等待秒数，默认 3。
        最大尝试次数 (Optional[int]):
            - None：无限重试（默认）
            - int：最多尝试指定次数，超出后返回 None

    Returns:
        Optional[requests.Response]:
            - 成功：返回响应对象（requests.Response）
            - 失败：返回 None
    """
    if not isinstance(url, str) or not url.strip():
        return None

    次数 = 0

    while True:
        try:
            响应 = requests.get(
                url=url,
                params=params,
                headers=headers,
                cookies=cookies,
                timeout=timeout,
                allow_redirects=allow_redirects,
                verify=verify,
                proxies=proxies,
            )

            状态码 = getattr(响应, "status_code", None)
            if isinstance(状态码, int) and 200 <= 状态码 < 300:
                return 响应

        except Exception:
            pass

        次数 += 1
        if 最大尝试次数 is not None and 次数 >= 最大尝试次数:
            return None

        time.sleep(重试间隔秒)