"""Extract 9-digit Sivas IDs from JSON tree files generated by jsonFromXlsx.py.

Collects Sivas numbers that sit one hierarchy level above the leaves
and writes them as 'nummer: bezeichnung' into a text file.

Usage:
    python extract_ids.py --filename KA135776
    python extract_ids.py --filename KA135776 --tab soll
    python extract_ids.py --all
"""

import argparse
import json
import os
import re
import sys
from pathlib import Path


RE_SIVAS = re.compile(r"^(\d{9})")


def is_leaf_value(v) -> bool:
    """True if v is a leaf entry (string, anzahl-dict, or laenge-dict)."""
    if isinstance(v, str):
        return True
    if isinstance(v, dict) and ("anzahl" in v or "laenge" in v):
        return True
    return False


def extract_ids_from_tree(tree: dict) -> dict[str, str]:
    """Collect 9-digit Sivas numbers one level above leaves.

    Returns dict of nummer -> bezeichnung.
    """
    ids: dict[str, str] = {}

    def walk(node: dict):
        for key, value in node.items():
            if not isinstance(value, dict) or "anzahl" in value or "laenge" in value:
                continue  # leaf, skip
            # Check if all children are leaves
            all_leaves = all(is_leaf_value(v) for v in value.values())
            m = RE_SIVAS.match(key)
            if all_leaves and value and m:
                nummer = m.group(1)
                # Bezeichnung from key: part after "nummer-", underscores back to spaces
                if len(key) > 9:
                    bez = key[10:].replace("_", " ")
                else:
                    bez = nummer
                ids[nummer] = bez
            else:
                walk(value)

    walk(tree)
    return ids


def process_json(json_path: Path, tab: str, results_dir: Path) -> int:
    """Extract IDs from one JSON file. Returns number of IDs found."""
    with open(json_path, encoding="utf-8") as f:
        tree = json.load(f)

    ids = extract_ids_from_tree(tree)

    # Derive project name: strip _ist/_soll suffix
    project_name = json_path.stem
    for suffix in ("_ist", "_soll"):
        if project_name.endswith(suffix):
            project_name = project_name[: -len(suffix)]
            break

    ids_path = results_dir / f"{project_name}_ids_{tab}.txt"
    with open(ids_path, "w", encoding="utf-8") as f:
        for nummer, bez in sorted(ids.items()):
            f.write(f"{nummer}: {bez}\n")

    print(f"  {json_path.name} -> {ids_path.name} ({len(ids)} IDs)")
    return len(ids)


def main():
    parser = argparse.ArgumentParser(
        description="Extrahiert 9-stellige Sivas-Nummern aus JSON-Baeumen im results/-Ordner."
    )
    parser.add_argument(
        "--filename",
        default=None,
        help="Suchmuster fuer JSON-Dateien im results/-Ordner (z.B. 'KA135776')",
    )
    parser.add_argument(
        "--tab",
        choices=["soll", "ist"],
        default="ist",
        help="Welches Tab gelesen wird: 'ist' oder 'soll' (default: ist)",
    )
    parser.add_argument(
        "--all",
        action="store_true",
        dest="process_all",
        help="Alle *_<tab>.json Dateien im results/-Ordner verarbeiten",
    )
    args = parser.parse_args()

    if not args.process_all and not args.filename:
        parser.error("Entweder --filename oder --all muss angegeben werden.")

    project_root = Path(os.environ.get("PROJECT", Path(__file__).resolve().parent.parent))
    results_dir = project_root / "results"

    if not results_dir.exists():
        print(f"FEHLER: results/-Ordner nicht gefunden: {results_dir}")
        sys.exit(1)

    pattern = f"*_{args.tab}.json"
    json_files = sorted(results_dir.glob(pattern))
    if args.filename:
        json_files = [f for f in json_files if args.filename.lower() in f.name.lower()]

    if not json_files:
        print(f"FEHLER: Keine JSON-Dateien mit Muster '{pattern}' in {results_dir} gefunden.")
        if args.filename:
            print(f"  (Filter: '{args.filename}')")
        sys.exit(1)

    print(f"Verarbeite {len(json_files)} JSON-Dateien aus {results_dir}\n")
    total_ids = 0
    for json_path in json_files:
        total_ids += process_json(json_path, args.tab, results_dir)

    print(f"\nFertig: {total_ids} IDs aus {len(json_files)} Dateien extrahiert.")


if __name__ == "__main__":
    main()
