from typing import Tuple, Dict, Any, Set, Iterable, List
from .normalize import normalize_mac, is_mac

DEFAULT_MAC_FIELDS: tuple[str, ...] = (
    "mac",
    "beacon_mac",
    "beaconMac",
    "device_mac",
    "deviceMac",
    "tag_mac",
    "tagMac",
)

def _first_present(item: dict, keys: Iterable[str]) -> str:
    for k in keys:
        if k in item and item.get(k):
            return str(item.get(k))
    return ""

def extract_beacon_macs(data: object, mac_fields: tuple[str, ...] = DEFAULT_MAC_FIELDS
                        ) -> Tuple[Set[str], Dict[str, Any], List[str]]:
    allowed: Set[str] = set()
    by_mac: Dict[str, Any] = {}
    invalid: List[str] = []

    items = None
    if isinstance(data, list):
        items = data
    elif isinstance(data, dict):
        for key in ("items", "beacons", "trackers", "data", "result"):
            v = data.get(key)
            if isinstance(v, list):
                items = v
                break

    if not items:
        return allowed, by_mac, invalid

    for item in items:
        if not isinstance(item, dict):
            continue
        raw = _first_present(item, mac_fields)
        mac = normalize_mac(raw)
        if mac and is_mac(mac):
            allowed.add(mac)
            by_mac[mac] = item
        else:
            if raw:
                invalid.append(str(raw))

    return allowed, by_mac, invalid
