from __future__ import annotations

from typing import Any, List, Sequence, Union


_路径类型 = Union[str, Sequence[Any]]


def 删除键_路径(
    数据: Any,
    键路径: _路径类型,
    分隔符: str = ".",
    键转字符串: bool = True,
) -> bool:
    """根据路径删除嵌套字典或列表中的目标项。

    功能说明:
        - 这个函数用于根据路径删除嵌套字典或列表中的目标项。
        - 当你拿到的是多层结构的数据时，可以直接传入路径，不用自己一层一层往下找。
        - 它适合处理接口返回值、配置数据、表单结构这类多层字典场景。

    Args:
        数据: 通常为 dict 或 list 的嵌套结构。
        键路径: 路径字符串或路径序列。
            - 字符串示例： "a.b.0.c"
            - 列表示例： ["a", "b", 0, "c"]
        分隔符: 字符串路径的分隔符，默认 "."。
        键转字符串: 当走 dict 路径时，是否将键统一转为 str。默认 True。

    Returns:
        删除成功时返回 ``True``；删除失败时返回 ``False``。
    """
    try:
        if isinstance(键路径, str):
            if 键路径 == "":
                return False
            路径列表: List[Any] = 键路径.split(分隔符)
        elif isinstance(键路径, (list, tuple)):
            if len(键路径) == 0:
                return False
            路径列表 = list(键路径)
        else:
            return False

        if not isinstance(数据, (dict, list)):
            return False

        if len(路径列表) == 1:
            父级 = 数据
            末段 = 路径列表[0]
        else:
            父级 = 数据
            for 段 in 路径列表[:-1]:
                if isinstance(父级, dict):
                    键名 = str(段) if 键转字符串 else 段
                    if 键名 not in 父级:
                        return False
                    父级 = 父级[键名]
                    continue

                if isinstance(父级, (list, tuple)):
                    try:
                        目标索引 = 段 if isinstance(段, int) else int(str(段))
                    except Exception:
                        return False

                    if 目标索引 < 0 or 目标索引 >= len(父级):
                        return False

                    父级 = 父级[目标索引]
                    continue

                return False

            末段 = 路径列表[-1]

        if isinstance(父级, dict):
            键名 = str(末段) if 键转字符串 else 末段
            if 键名 not in 父级:
                return False
            del 父级[键名]
            return True

        if isinstance(父级, list):
            try:
                目标索引 = 末段 if isinstance(末段, int) else int(str(末段))
            except Exception:
                return False

            if 目标索引 < 0 or 目标索引 >= len(父级):
                return False

            del 父级[目标索引]
            return True

        return False
    except Exception:
        return False


if __name__ == "__main__":
    print("===== 示例1：基础用法 =====")
    数据 = {"用户": {"信息": [{"城市": "上海", "年龄": 18}]}}
    print("结果:", 删除键_路径(数据, "用户.信息.0.城市"))
    print("数据:", 数据)

    print("\n===== 示例2：使用列表路径 =====")
    数据 = {"用户": {"信息": [{"城市": "北京", "年龄": 20}]}}
    print("结果:", 删除键_路径(数据, ["用户", "信息", 0, "年龄"]))
    print("数据:", 数据)

    print("\n===== 示例3：边界情况-空路径 =====")
    数据 = {"用户": {"信息": [{"城市": "上海"}]}}
    print("结果:", 删除键_路径(数据, ""))
    print("数据:", 数据)

    print("\n===== 示例4：异常情况-数据不是字典或列表 =====")
    数据 = []
    print("结果:", 删除键_路径(数据, "用户.信息.0.城市"))
    print("数据:", 数据)

    print("\n===== 示例5：特殊值情况-路径不存在 =====")
    数据 = {"用户": {"信息": [{"城市": None, "标签": ""}]}}
    print("结果:", 删除键_路径(数据, "用户.信息.0.电话"))
    print("数据:", 数据)

    print("\n===== 示例6：应用场景-删除订单中的联系人 =====")
    数据 = {"订单": {"收货信息": [{"联系人": "张三", "电话": "123456"}]}}
    print("结果:", 删除键_路径(数据, "订单.收货信息.0.联系人"))
    print("数据:", 数据)
