from typing import Optional, Dict

import requests

from Proxy_tools import ProxyTool
from darren_utils import cookie_string_to_dict


def darren_http(method: str, url: str, headers: Optional[Dict] = None,
                cookies: Optional[Dict] = None, proxies: Optional[Dict] = None,
                use_proxy: bool = True, max_retries: int = 3, timeout: int = 10,
                **kwargs) -> tuple[Optional[requests.Response], Optional[Dict]]:
    """
    封装的HTTP请求函数，支持自动重试和代理切换

    Args:
        method: HTTP方法 ('GET', 'POST', 'PUT', 'DELETE' 等)
        url: 请求URL
        headers: 请求头
        cookies: Cookie字典
        proxies: 传入的代理配置
        use_proxy: 是否使用代理
        max_retries: 最大重试次数
        timeout: 超时时间（秒）
        **kwargs: 其他传递给requests的参数

    Returns:
        tuple[Optional[requests.Response], Optional[Dict]]:
        返回(response对象, 使用的代理)的元组，失败时返回(None, None)

    Example:
        >>> response, proxy = darren_http('GET', 'https://httpbin.org/get')
        >>> if response:
        ...     print(response.status_code)
    """
    headers = headers or {}
    # 如果传入了代理参数，优先使用传入的
    current_proxies = proxies
    for attempt in range(max_retries + 1):
        # 如果启用了代理但没有有效的代理配置，则动态获取
        if use_proxy and not current_proxies:
            proxy = ProxyTool.get_one_proxy()
            if proxy:
                current_proxies = proxy
        try:
            if isinstance(cookies, str):
                cookies = cookie_string_to_dict(cookies)
            response = requests.request(
                method=method,
                url=url,
                headers=headers,
                cookies=cookies,
                proxies=current_proxies,
                timeout=timeout,
                **kwargs
            )
            return response, current_proxies
        except Exception as e:
            if attempt < max_retries:
                print(f"第 {attempt + 1} 次请求失败: {type(e).__name__}, {e}正在重试...")
                current_proxies = None
            else:
                return None, None

    return None, None


# 便捷函数
def darren_get(url: str, headers: Optional[Dict] = None, cookies: Optional[Dict] = None,
               proxies: Optional[Dict] = None, use_proxy: bool = True,
               max_retries: int = 3, timeout: int = 10, **kwargs) -> tuple[Optional[requests.Response], Optional[Dict]]:
    """GET请求的便捷函数"""
    return darren_http('GET', url, headers, cookies, proxies, use_proxy, max_retries, timeout, **kwargs)


def darren_post(url: str, headers: Optional[Dict] = None, cookies: Optional[Dict] = None,
                proxies: Optional[Dict] = None, use_proxy: bool = True,
                max_retries: int = 3, timeout: int = 10, **kwargs) -> tuple[
    Optional[requests.Response], Optional[Dict]]:
    """POST请求的便捷函数"""
    return darren_http('POST', url, headers, cookies, proxies, use_proxy, max_retries, timeout, **kwargs)


def darren_put(url: str, headers: Optional[Dict] = None, cookies: Optional[Dict] = None,
               proxies: Optional[Dict] = None, use_proxy: bool = True,
               max_retries: int = 3, timeout: int = 10, **kwargs) -> tuple[Optional[requests.Response], Optional[Dict]]:
    """PUT请求的便捷函数"""
    return darren_http('PUT', url, headers, cookies, proxies, use_proxy, max_retries, timeout, **kwargs)


def darren_delete(url: str, headers: Optional[Dict] = None, cookies: Optional[Dict] = None,
                  proxies: Optional[Dict] = None, use_proxy: bool = True,
                  max_retries: int = 3, timeout: int = 10, **kwargs) -> tuple[
    Optional[requests.Response], Optional[Dict]]:
    """DELETE请求的便捷函数"""
    return darren_http('DELETE', url, headers, cookies, proxies, use_proxy, max_retries, timeout, **kwargs)
