from __future__ import annotations

import json
from collections import Counter
from typing import Any, Dict, List, Union, Optional


def 遍历_键_取层级(
    数据对象: Union[Dict[str, Any], List[Any], str, bytes, bytearray],
    目标键: str,
    *,
    去重: bool = True,
    排序: bool = True,
    返回次数: bool = False,
    最浅: bool = False,
    最深: bool = False,
) -> Union[List[int], Dict[int, int]]:
    """
    遍历嵌套数据结构，返回目标键出现过的层级（depth）。

    层级定义：
        - 根节点为第 0 层。
        - 进入 dict 的 value，层级 +1。
        - 进入 list 的 element，层级 +1。
        - 仅 dict 节点具备键；list 仅作为容器参与层级计算。

    行为说明：
        - 本函数会遍历所有 dict 节点；当 dict 中包含 目标键 时，
          记录该键出现的层级（即该 dict 节点所在层级）。
        - 若 返回次数=True，则统计各层级出现次数并返回映射。

    Args:
        数据对象:
            待遍历的数据结构，支持 dict、list，
            以及可被解析为 JSON 的 str、bytes、bytearray。
        目标键:
            需要查询出现层级的键名。
        去重:
            是否对层级结果去重。仅在 返回次数=False 时生效。
        排序:
            是否对层级结果升序排序。仅在 返回次数=False 时生效。
        返回次数:
            是否返回“层级 -> 出现次数”的统计结果。
        最浅:
            仅返回最浅（最小）层级。与 最深 互斥时建议只启用一个。
        最深:
            仅返回最深（最大）层级。与 最浅 互斥时建议只启用一个。

    Returns:
        list[int] | dict[int, int]:
            - 返回次数=False：返回层级列表（可去重、可排序，可仅返回最浅/最深）。
            - 返回次数=True：返回各层级出现次数的映射 {层级: 次数}。
            - 未命中或发生异常时返回空列表 [] 或空字典 {}（与返回类型保持一致）。
    """
    try:
        if isinstance(数据对象, (str, bytes, bytearray)):
            数据对象 = json.loads(数据对象)

        计数: Counter[int] = Counter()
        _递归收集_键出现层级(数据对象, 目标键, 0, 计数)

        if 返回次数:
            return dict(计数)

        层级们 = list(计数.keys())
        if not 层级们:
            return []

        if 最浅 and 最深:
            # 同时指定时，按“都满足不了就给全量”的保守策略
            # 也可以改成优先最浅/最深之一，你按个人口味调整。
            pass
        elif 最浅:
            return [min(层级们)]
        elif 最深:
            return [max(层级们)]

        if 去重:
            # keys 本来就是去重的，这里保留参数语义一致性
            pass

        if 排序:
            层级们.sort()

        return 层级们
    except Exception:
        return {} if 返回次数 else []


def _递归收集_键出现层级(
    节点: Any,
    目标键: str,
    当前层级: int,
    计数: Counter[int],
) -> None:
    """深度优先遍历：遇到包含目标键的 dict，记录其所在层级。"""
    if isinstance(节点, dict):
        if 目标键 in 节点:
            计数[当前层级] += 1
        for v in 节点.values():
            _递归收集_键出现层级(v, 目标键, 当前层级 + 1, 计数)
    elif isinstance(节点, list):
        for el in 节点:
            _递归收集_键出现层级(el, 目标键, 当前层级 + 1, 计数)


复杂数据_层级测试 = {
    "meta": {
        "trace_id": "T-001",
        "flags": [{"k": "debug", "v": True}, {"k": "beta", "v": False}],
        "owner": {"name": "Zeng", "tag": "root_owner_tag"}
    },
    "data": [
        {
            "user": {
                "id": 101,
                "tag": "u101_tag",
                "profile": {
                    "name": "Alice",
                    "tag": "profile_tag",
                    "tags": [
                        {"k": "vip", "tag": "kv_tag_1"},
                        {"k": "level", "tag": "kv_tag_2"},
                    ],
                },
            },
            "orders": [
                {
                    "order_id": "A-100",
                    "tag": "order_tag",
                    "items": [
                        {"sku": "S1", "price": 10, "tag": "item_tag_1"},
                        {"sku": "S2", "price": 20},
                    ],
                },
                {
                    "order_id": "A-101",
                    "items": [],
                },
            ],
        },
        {
            "user": {
                "id": 102,
                "profile": {
                    "name": "Bob",
                    "tags": [],
                },
            },
            "orders": "noise_string",  # 原子值：后面不会再有键
        },
    ],
    "extra": [
        [
            {"misc": {"tag": "misc_tag_1", "flag": True}},
            {"misc": [{"tag": "misc_tag_2a"}, {"tag": "misc_tag_2b"}]},
        ],
        {"tag": "extra_tag_dict"},
        123,
        None,
    ],
    "tag": "root_tag",
}