from __future__ import annotations

from typing import Any
from xml.etree import ElementTree as ET

XML_LANG = "{http://www.w3.org/XML/1998/namespace}lang"


def _text(value: Any) -> str:
    return str(value or "").strip()


def _labels(node: ET.Element) -> dict[str, dict[str, str]]:
    result = {
        "ru": {"label": "", "description": "", "short": ""},
        "en": {"label": "", "description": "", "short": ""},
    }
    for label in node.findall("./label"):
        language = _text(label.attrib.get(XML_LANG) or label.attrib.get("lang") or "ru").lower()
        if language not in result:
            continue
        result[language] = {
            "label": _text(label.text),
            "description": _text(label.attrib.get("description")),
            "short": _text(label.attrib.get("short")),
        }
    return result


def _merge_entry(target: dict[str, Any], source: dict[str, Any]) -> None:
    for language in ("ru", "en"):
        current = target.setdefault(language, {"label": "", "description": "", "short": ""})
        incoming = source.get(language, {})
        for key in ("label", "description", "short"):
            if not current.get(key) and incoming.get(key):
                current[key] = incoming[key]


def parse_navigation_labels_xml(content: bytes | str) -> dict[str, Any]:
    raw = content.encode("utf-8") if isinstance(content, str) else content
    root = ET.fromstring(raw)
    columns: dict[str, dict[str, Any]] = {}
    by_section: dict[str, dict[str, dict[str, Any]]] = {}
    sections: dict[str, dict[str, Any]] = {}

    for item in root.findall(".//list//item[@section]"):
        section = _text(item.attrib.get("section"))
        if section:
            entry = _labels(item)
            target = sections.setdefault(section, {})
            _merge_entry(target, entry)

    for columns_node in root.findall(".//columns"):
        section_names = [part for part in _text(columns_node.attrib.get("sections")).split() if part]
        for index, cell in enumerate(columns_node.findall("./cell")):
            ref = _text(cell.attrib.get("ref"))
            labels = _labels(cell)
            if not ref:
                ru = labels.get("ru", {}).get("label", "").casefold()
                en = labels.get("en", {}).get("label", "").casefold()
                if ru in {"игрок", "хоккеист"} or en == "player":
                    ref = "player"
                elif ru in {"клуб", "команда"} or en == "team":
                    ref = "team"
                elif ru == "№" or en in {"№", "no.", "number"}:
                    ref = "number"
                elif index == 0:
                    ref = "rank"
                else:
                    continue
            entry = {
                **labels,
                "datatype": _text(cell.attrib.get("datatype")),
                "sortable": _text(cell.attrib.get("sortable")),
                "default": _text(cell.attrib.get("default")),
            }
            global_entry = columns.setdefault(ref, {})
            _merge_entry(global_entry, entry)
            for key in ("datatype", "sortable", "default"):
                if not global_entry.get(key) and entry.get(key):
                    global_entry[key] = entry[key]
            for section in section_names:
                section_entry = by_section.setdefault(section, {}).setdefault(ref, {})
                _merge_entry(section_entry, entry)
                for key in ("datatype", "sortable", "default"):
                    if not section_entry.get(key) and entry.get(key):
                        section_entry[key] = entry[key]

    return {
        "available": bool(columns or sections),
        "columns": columns,
        "columns_by_section": by_section,
        "sections": sections,
    }
