# BEGIN CHANGE: parse RME visual item-class scan into JSON
"""Parse 'itens imagens pro items otb criar e editar.txt' into class -> ids."""
from __future__ import annotations

import json
import re
import sys
from pathlib import Path

SECTION_MAP = {
    "corpses": "corpses",
    "magic forcefields": "teleports",
    "decoration": "decoration",
    "trainers": "trainers",
    "beds": "beds",
    "walls": "walls",
    "stairs": "stairs",
    "grounds": "grounds",
    "statues": "statues",
    "imbuements e valuables": "valuables",
    "potions": "potions",
    "ammunition": "ammunition",
    "armors": "armor",
    "legs": "legs",
    "distance": "distance",
    "club": "club",
    "helmet": "helmet",
    "spellbooks": "spellbooks",
    "wands e rods": "wand",
}

# Digit typos: span would be thousands of IDs or exceed uint16 OTB max (65535).
RANGE_FIX = {
    (45772, 75761): (45772, 45761),
    (45742, 75739): (45742, 45739),
    (11368, 33161): (33168, 33161),
    (17207, 27199): (17207, 17199),
    (14041, 15034): (15041, 15034),
}


TOKEN_RE = re.compile(
    r"(\d+)\s+a\s+(\d+)|(\d+)",
    re.I,
)


def parse_tokens(blob: str) -> tuple[list[int], list[tuple[int, int, int, int]]]:
    blob = re.sub(r"\b[eE]\b", " ", blob)
    blob = blob.replace(" A ", " a ")
    leftover = TOKEN_RE.sub(" ", blob)
    leftover = re.sub(r"[,;]+", " ", leftover).strip()
    if leftover:
        raise ValueError("unparsed leftover: %r" % (leftover,))
    ids: list[int] = []
    ranges: list[tuple[int, int, int, int]] = []
    for m in TOKEN_RE.finditer(blob):
        if m.group(1) is not None:
            a, b = int(m.group(1)), int(m.group(2))
            aa, bb = RANGE_FIX.get((a, b), (a, b))
            lo, hi = min(aa, bb), max(aa, bb)
            ids.extend(range(lo, hi + 1))
            ranges.append((a, b, aa, bb))
        else:
            ids.append(int(m.group(3)))
    return ids, ranges


def parse_file(text: str) -> dict[str, dict]:
    current = None
    buf: list[str] = []
    sections: dict[str, dict] = {}

    def flush() -> None:
        if current is None:
            return
        blob = " ".join(buf)
        ids, ranges = parse_tokens(blob)
        sections[current] = {
            "ids": sorted(set(ids)),
            "ranges": ranges,
            "blob": blob,
        }

    for line in text.splitlines():
        s = line.strip()
        if not s:
            continue
        s = re.sub(r"\s*-\s*esse\b.*$", "", s, flags=re.I).strip()
        if not s:
            continue
        key = s.lower()
        matched = None
        for h in SECTION_MAP:
            if key == h or key.startswith(h + " "):
                matched = h
                break
        if matched:
            flush()
            current = SECTION_MAP[matched]
            rest = s[len(matched) :].strip()
            buf = [rest] if rest else []
            continue
        buf.append(s)
    flush()
    return sections


def main() -> int:
    src = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(
        r"P:\OT\OTSERVER\pedro\otx2_reseted\itens imagens pro items otb criar e editar.txt"
    )
    sections = parse_file(src.read_text(encoding="utf-8"))
    overlaps: list[str] = []
    owner: dict[int, str] = {}
    for cls, data in sections.items():
        for i in data["ids"]:
            if i in owner:
                overlaps.append("%s: %s vs %s" % (i, owner[i], cls))
            owner[i] = cls
        fixes = [(a, b, aa, bb) for a, b, aa, bb in data["ranges"] if (a, b) != (aa, bb)]
        print(
            "%-12s %5d ids  range_fixes=%s"
            % (cls, len(data["ids"]), fixes or "-")
        )
    print("total unique", len(owner))
    print("ids > 65535", sum(1 for i in owner if i > 65535))
    if overlaps:
        print("OVERLAPS", overlaps)
    out = {cls: data["ids"] for cls, data in sections.items()}
    dst = Path(__file__).with_name("visual_item_scan.json")
    dst.write_text(json.dumps(out, indent=0), encoding="utf-8")
    print("wrote", dst, "bytes", dst.stat().st_size)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
# END CHANGE
