# -*- coding: utf-8 -*-
"""
统一 HTTP 请求工具 — 直连优先，代理降级
所有模块统一使用 http_get / http_post / make_session

策略：
  1. 优先直连（proxies={}），适合国内代理已配置但偶发不稳定的场景
  2. 直连失败时自动降级走 PROXIES 重试一次
  3. 两者都失败则抛异常，由调用方处理

用法:
  from exchange.http import http_get, http_post, make_session
"""

import time
import logging
import requests
from config import PROXIES

logger = logging.getLogger("MyTrader")


def http_get(url, *, params=None, headers=None, timeout=12, session=None):
    """
    GET 请求：有代理先走代理，否则直连。
    session: 可传入已有 Session（如 OKX 需要鉴权头的情况），否则使用临时 Session。
    """
    kwargs = dict(params=params, headers=headers, timeout=timeout)
    _req = session.get if session else requests.get

    # 1. 代理优先（如果已配置）
    if PROXIES:
        try:
            r = _req(url, proxies=PROXIES, **kwargs)
            r.raise_for_status()
            return r
        except Exception as e_proxy:
            logger.debug(f"[HTTP] 代理失败，降级直连: {url} — {e_proxy}")

    # 2. 直连
    try:
        r = _req(url, proxies={}, **kwargs)
        r.raise_for_status()
        return r
    except Exception as e_direct:
        raise requests.RequestException(f"请求失败: {url} — {e_direct}") from e_direct


def http_post(url, *, json=None, data=None, files=None, headers=None, timeout=12, session=None):
    """
    POST 请求：有代理先走代理，否则直连。
    files: multipart 上传（如 Telegram sendPhoto）
    """
    kwargs = dict(json=json, data=data, files=files, headers=headers, timeout=timeout)
    _req = session.post if session else requests.post

    # 1. 代理优先（如果已配置）
    if PROXIES:
        try:
            r = _req(url, proxies=PROXIES, **kwargs)
            r.raise_for_status()
            return r
        except Exception as e_proxy:
            logger.debug(f"[HTTP] 代理失败，降级直连: {url} — {e_proxy}")

    # 2. 直连
    try:
        r = _req(url, proxies={}, **kwargs)
        r.raise_for_status()
        return r
    except Exception as e_direct:
        raise requests.RequestException(f"请求失败: {url} — {e_direct}") from e_direct


def make_session(proxies=None) -> requests.Session:
    """
    创建带默认配置的 Session。
    proxies=None  → 不设置代理（直连），由 http_get/http_post 按需覆盖
    proxies=PROXIES → 固定走代理（WebSocket 等不经过统一函数的场景）
    """
    s = requests.Session()
    if proxies is not None:
        s.proxies = proxies
    return s


def http_get_retry(url, *, retries=3, backoff=2, **kwargs):
    """带重试的 GET，每次失败等待 backoff 秒后重试。"""
    last_err = None
    for i in range(retries):
        try:
            return http_get(url, **kwargs)
        except Exception as e:
            last_err = e
            if i < retries - 1:
                time.sleep(backoff * (i + 1))
    raise last_err


def http_post_retry(url, *, retries=3, backoff=2, **kwargs):
    """带重试的 POST，每次失败等待 backoff 秒后重试。"""
    last_err = None
    for i in range(retries):
        try:
            return http_post(url, **kwargs)
        except Exception as e:
            last_err = e
            if i < retries - 1:
                time.sleep(backoff * (i + 1))
    raise last_err
