#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as ET
import re
import os

def process_qet_file(filepath, output_path):
    # EINSTELLUNGEN
    PIXEL_PRO_ZEICHEN = 5.5

    try:
        tree = ET.parse(filepath)
        root = tree.getroot()

        parent_map = {c: p for p in tree.iter() for c in p}

        # Ein globales Wörterbuch (Dictionary) aller Bauteile anhand ihrer UUID erstellen.
        uuid_map = {}
        for el in root.iter('element'):
            el_uuid = el.get('uuid')
            if el_uuid:
                uuid_map[el_uuid] = el

        for diagram in root.iter('diagram'):
            folio = diagram.get('folio', '')
            counters = {}
            valid_elements = []

            for element in diagram.iter('element'):
                # 1. Prüfen, ob in ausgeschlossener Collection
                in_excluded_collection = False
                curr = element
                while curr in parent_map:
                    curr = parent_map[curr]
                    if curr.tag == 'collection':
                        link_type = curr.get('link_type')
                        if link_type in ['next_report', 'previous_report']:
                            in_excluded_collection = True
                            break
                if in_excluded_collection:
                    continue

                # 2. Prüfen, ob Formula einen Eintrag hat
                formula_info = element.find(".//elementInformation[@name='formula']")
                if formula_info is not None and formula_info.text and formula_info.text.strip():
                    continue

                # 3 & 4. Label prüfen
                label_info = element.find(".//elementInformation[@name='label']")
                if label_info is None or not label_info.text:
                    continue

                label_text = label_info.text.strip()
                match = re.fullmatch(r'-([A-Za-z]{1,2})', label_text)
                if not match:
                    continue

                prefix = match.group(1)
                x = float(element.get('x', 0))
                y = float(element.get('y', 0))

                valid_elements.append({
                    'element': element,
                    'x': x,
                    'y': y,
                    'prefix': prefix,
                    'label_info': label_info,
                    'old_label': label_text
                })

            # 5. Sortieren
            valid_elements.sort(key=lambda item: (item['y'], item['x']))

            # 6. Nummerierung und Textausrichtung anwenden
            for item in valid_elements:
                prefix = item['prefix']
                counters[prefix] = counters.get(prefix, 0) + 1

                new_label = f"-{folio}{prefix}{counters[prefix]}"
                item['label_info'].text = new_label

                for dyn_text in item['element'].findall('.//dynamic_elmt_text'):
                    info_name = dyn_text.find('info_name')
                    if info_name is not None and info_name.text == 'label':
                        text_node = dyn_text.find('text')
                        if text_node is not None:
                            text_node.text = new_label

                            # X-Koordinate bei Rechtsausrichtung anpassen
                            halignment = dyn_text.get('Halignment', '')
                            if halignment == 'AlignRight':
                                len_diff = len(new_label) - len(item['old_label'])
                                if len_diff > 0:
                                    # Berechnung des absoluten Versatzes
                                    offset = len_diff * PIXEL_PRO_ZEICHEN

                                    try:
                                        # 1. Master anpassen (mit Prüfung auf Rotation)
                                        current_x = float(dyn_text.get('x', 0))
                                        rotation = dyn_text.get('rotation', '0')

                                        if rotation == '180':
                                            new_x = current_x + offset  # Vorzeichen gedreht
                                        else:
                                            new_x = current_x - offset

                                        dyn_text.set('x', str(round(new_x, 4)))

                                        # 2. Verbundene Slaves suchen und ebenfalls verschieben
                                        for link in item['element'].findall('.//link_uuid'):
                                            slave_uuid = link.get('uuid')
                                            if slave_uuid and slave_uuid in uuid_map:
                                                slave_el = uuid_map[slave_uuid]
                                                for s_dyn_text in slave_el.findall('.//dynamic_elmt_text'):
                                                    s_info = s_dyn_text.find('info_name')
                                                    if s_info is not None and s_info.text == 'label':
                                                        if s_dyn_text.get('Halignment', '') == 'AlignRight':
                                                            try:
                                                                s_current_x = float(s_dyn_text.get('x', 0))
                                                                s_rotation = s_dyn_text.get('rotation', '0')

                                                                if s_rotation == '180':
                                                                    s_new_x = s_current_x + offset  # Vorzeichen gedreht
                                                                else:
                                                                    s_new_x = s_current_x - offset

                                                                s_dyn_text.set('x', str(round(s_new_x, 4)))
                                                            except ValueError:
                                                                pass
                                    except ValueError:
                                        pass

        tree.write(output_path, encoding='utf-8', xml_declaration=True)
        print(f"Erfolgreich gespeichert: {output_path}")

    except Exception as e:
        print(f"Kritischer Fehler bei der Nummerierung: {str(e)}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Verwendung: python Nummerierung.py <eingangs_qet_datei> <ausgangs_qet_datei>", file=sys.stderr)
        sys.exit(1)

    input_file = sys.argv[1]
    output_file = sys.argv[2]

    process_qet_file(input_file, output_file)
