import re
import json
import sys

def build_label_dictionary(struct_json_file):
    """
    Wczytuje plik .json z drzewem (type, numbering, label, children)
    i tworzy słownik mapujący 'itm:xxx' -> '...numbering...'.
    """
    with open(struct_json_file, 'r', encoding='utf-8') as f:
        data = json.load(f)

    label_map = {}

    def traverse(nodes):
        for node in nodes:
            lbl = node.get('label', '')
            if lbl.startswith('itm:'):
                # np. 'itm:srodroczna-terminy'
                numbering = node.get('numbering', '')
                label_map[lbl] = numbering
            # rekurencja po dzieciach
            if 'children' in node and isinstance(node['children'], list):
                traverse(node['children'])

    traverse(data)
    return label_map


def replace_refs_in_tex(tex_in, tex_out, label_dict):

    with open(tex_in, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    # Regex sprawdza, czy występuje opcjonalny nawias otwierający, 
    # polecenie \ref{itm:...}, i opcjonalny nawias zamykający.
    #  - group(1) => '[' lub None
    #  - group(2) => 'itm:...'  (np. 'itm:srodroczna-terminy')
    #  - group(3) => ']' lub None
    pattern = re.compile(r'(\[)?\\ref\{(itm:[^}]+)\}(\])?')

    def ref_replacer(match):
        bracket_open  = match.group(1)  # '[' albo None
        key           = match.group(2)  # np. 'itm:srodroczna-terminy'
        bracket_close = match.group(3)  # ']' albo None

        if key in label_dict:
            numbering = label_dict[key]
            # zamieniamy na \hyperref[itm:xxx]{numbering} – bez nawiasów kwadratowych
            return f"\\hyperref[{key}]{{{numbering}}}"
        else:
            # brak w słowniku -> zostawiamy oryginalny zapis
            # (wraz z ewentualnymi nawiasami)
            left  = bracket_open if bracket_open else ''
            right = bracket_close if bracket_close else ''
            return f"{left}\\ref{{{key}}}{right}"

    new_lines = []
    for line in lines:
        new_line = pattern.sub(ref_replacer, line)
        new_lines.append(new_line)

    with open(tex_out, 'w', encoding='utf-8') as f:
        f.writelines(new_lines)


def main():
    # Domyślne nazwy plików:
    default_struct_json = "../main-struct.json"
    default_tex_in      = "../main.tex"
    default_tex_out     = "../m.tex"

    args = sys.argv[1:]
    if len(args) == 0:
        # brak argumentów -> używamy domyślnych
        struct_json_file = default_struct_json
        tex_in_file      = default_tex_in
        tex_out_file     = default_tex_out
    elif len(args) == 1:
        # 1 argument (plik .json), rest domyślny
        struct_json_file = args[0]
        tex_in_file      = default_tex_in
        tex_out_file     = default_tex_out
    elif len(args) == 2:
        # 2 argumenty: .json + .tex (in), out = m.tex
        struct_json_file = args[0]
        tex_in_file      = args[1]
        tex_out_file     = default_tex_out
    elif len(args) == 3:
        # 3 argumenty: .json + .tex(in) + .tex(out)
        struct_json_file = args[0]
        tex_in_file      = args[1]
        tex_out_file     = args[2]
    else:
        print("Użycie:")
        print("  python script.py   # domyślne: ../main-struct.json, ../main.tex => m.tex")
        print("  python script.py PLIK.json")
        print("  python script.py PLIK.json in.tex")
        print("  python script.py PLIK.json in.tex out.tex")
        sys.exit(1)

    label_map = build_label_dictionary(struct_json_file)
    replace_refs_in_tex(tex_in_file, tex_out_file, label_map)

    print(f"Gotowe! Zmodyfikowany plik został zapisany do: {tex_out_file}")


if __name__ == "__main__":
    main()

