from __future__ import annotations
from typing import Any, Optional


def 取响应文本(
    响应对象: Any,
    默认编码: str = "utf-8",
    errors: str = "replace",
) -> Optional[str]:
    """
    从 HTTP 响应对象（或文本/二进制）中安全获取文本内容。

    本函数用于统一“响应对象 / 文本 / bytes”的取文本逻辑，减少上层重复判断，
    并保证在批量请求、自动化采集等场景中稳定运行（不抛异常）。

    支持的输入类型：
        - requests.Response：优先使用其 text / content / encoding 信息
        - str：原样返回
        - bytes / bytearray：按编码解码为 str
        - None：返回 None

    编码策略（从优到劣）：
        1) 若响应对象存在 encoding 且为 str → 优先使用
        2) 使用 默认编码（默认 utf-8）
        3) 最后兜底 latin-1（几乎不会失败，但可能出现乱码）

    Args:
        响应对象 (Any): HTTP 响应对象，或 str/bytes/None。
        默认编码 (str): 当无法确定编码时使用的默认编码。
        errors (str): 解码错误处理策略，默认 "replace"（用替换符避免异常）。

    Returns:
        Optional[str]:
            - 成功：返回文本内容（str）
            - 失败：返回 None
    """
    try:
        if 响应对象 is None:
            return None

        if isinstance(响应对象, str):
            return 响应对象

        if isinstance(响应对象, (bytes, bytearray)):
            数据 = bytes(响应对象)
            try:
                return 数据.decode(默认编码, errors=errors)
            except Exception:
                return 数据.decode("latin-1", errors=errors)

        # 处理类似 requests.Response 的对象
        # 1) 优先尝试 .text（requests 会结合 encoding 推断）
        文本 = getattr(响应对象, "text", None)
        if isinstance(文本, str) and 文本 != "":
            return 文本

        # 2) 再尝试 .content（bytes），自行解码
        内容 = getattr(响应对象, "content", None)
        if isinstance(内容, (bytes, bytearray)):
            数据 = bytes(内容)
            编码 = getattr(响应对象, "encoding", None)
            if isinstance(编码, str) and 编码.strip():
                try:
                    return 数据.decode(编码, errors=errors)
                except Exception:
                    pass

            try:
                return 数据.decode(默认编码, errors=errors)
            except Exception:
                return 数据.decode("latin-1", errors=errors)

        return None
    except Exception:
        return None