import pydicom
import os
import file_management
import network_utils
import asyncio

def is_dicom_file(file_path):
    try:
        pydicom.dcmread(file_path, stop_before_pixels=True)
        return True
    except (pydicom.errors.InvalidDicomError, IOError, OSError, Exception):
        return False

def extract_patient_info(transfer_folder):
    print("Extract patient data")
    try:
        for root, dirs, files in os.walk(transfer_folder):
            for file in files:
                file_path = os.path.join(root, file)
                if is_dicom_file(file_path):
                    try:
                        ds = pydicom.dcmread(file_path)
                        if 'PatientName' in ds and 'PatientBirthDate' in ds:
                            name_vorname = str(ds.PatientName).strip()
                            geburtsdatum = ds.PatientBirthDate
                            return name_vorname, geburtsdatum
                    except Exception as e:
                        print(f"Fehler beim Lesen der DICOM-Datei {file_path}: {e}")
                        continue
    except Exception as e:
        print(f"Fehler beim Lesen der DICOM-Dateien: {e}")
        return None, None
    return None, None

def extract_modality(transfer_folder):
    print("Extract modality data")
    for root, dirs, files in os.walk(transfer_folder):
        for file in files:
            file_path = os.path.join(root, file)
            if is_dicom_file(file_path):
                try:
                    ds = pydicom.dcmread(file_path)
                    # Überprüfe, ob die gewünschten DICOM-Tags vorhanden sind
                    if 'StudyDate' in ds and 'StudyDescription' in ds:
                        study_date = ds.StudyDate
                        modality = ds.StudyDescription
                        print(f"Extracted modality data from {file_path}")
                        print(study_date)
                        print(modality)
                        return study_date, modality
                except Exception as e:
                    print(f"Fehler beim Lesen der DICOM-Datei {file_path}: {e}")
    print("Keine entsprechenden DICOM-Dateien gefunden.")
    return None, None

def update_patient_id_in_transfer_folder(transfer_folder, new_patient_id):
    if not transfer_folder or not os.path.exists(transfer_folder):
        print(f"FEHLER: Transferordner existiert nicht: {transfer_folder}")
        return
    
    if not new_patient_id:
        print("FEHLER: Keine Patienten-ID angegeben")
        return
    
    for root, dirs, files in os.walk(transfer_folder):
        for file in files:
            file_path = os.path.join(root, file)
            if not is_dicom_file(file_path):
                try:
                    os.remove(file_path)
                    print(f"Datei {file_path} wurde gelöscht.")
                except OSError as e:
                    print(f"Fehler beim Löschen der Datei {file_path}: {e}")
            else:
                print(f"Datei {file_path} wurde überprüft und behalten.")
                try:
                    ds = pydicom.dcmread(file_path)  # Lese die DICOM-Datei
                    ds.PatientID = new_patient_id  # Aktualisiere das PatientID-Feld
                    ds.save_as(file_path)  # Speichere die aktualisierte DICOM-Datei
                    print(f"PatientID in {file_path} wurde zu {new_patient_id} aktualisiert.")
                except (pydicom.errors.InvalidDicomError, IOError, OSError) as e:
                    print(f"Fehler beim Aktualisieren der PatientID in {file_path}: {e}")
                except Exception as e:
                    print(f"Unerwarteter Fehler beim Aktualisieren der PatientID in {file_path}: {e}")

def update_patient_info_in_transfer_folder(transfer_folder, new_name, new_firstname, new_birthdate):
    if not transfer_folder or not os.path.exists(transfer_folder):
        print(f"FEHLER: Transferordner existiert nicht: {transfer_folder}")
        return []
    
    if not new_name or not new_firstname or not new_birthdate:
        print("FEHLER: Unvollständige Patientendaten")
        return []
    
    changed_files = []
    for root, dirs, files in os.walk(transfer_folder):
        for file in files:
            file_path = os.path.join(root, file)
            if not is_dicom_file(file_path):
                continue
            try:
                ds = pydicom.dcmread(file_path)  # Lese die DICOM-Datei
                ds.PatientName = f"{new_name}^{new_firstname}"  # Aktualisiere das Patientenname-Feld
                ds.PatientBirthDate = new_birthdate  # Aktualisiere das Patientengeburtsdatum-Feld
                ds.save_as(file_path)  # Speichere die aktualisierte DICOM-Datei
                changed_files.append(file_path)
                print(f"Patienteninformationen in {file_path} wurden aktualisiert.")
            except (pydicom.errors.InvalidDicomError, IOError, OSError) as e:
                print(f"Fehler beim Aktualisieren der Patienteninformationen in {file_path}: {e}")
            except Exception as e:
                print(f"Unerwarteter Fehler beim Aktualisieren der Patienteninformationen in {file_path}: {e}")

    print(f"Anzahl geänderter Dateien: {len(changed_files)}")
    return changed_files

async def process_dicom_files(transfer_folder, gui, name, vorname, geburtsdatum, server_url, server_username, server_pw):
    print(f"TRANSFER_FOLDER: {transfer_folder}")
    print("Verarbeitung der DICOM-Dateien gestartet.")  # Debugging-Ausgabe
    # Nach der ersten Datei im Transfer-Ordner suchen, die das DICOM-Attribut PatientData hat
    
    patient_info = extract_patient_info(transfer_folder)
    if patient_info is not None:
        name_vorname_source, geburtsdatum_source = patient_info
        if name_vorname_source and geburtsdatum_source:
            print(f"Gefundene Patienteninformationen: {name_vorname_source}, {geburtsdatum_source}")
            # Weitere Verarbeitungsschritte
            name_source, vorname_source = file_management.format_patient_name(name_vorname_source)
            geburtsdatum_source_formatted = file_management.format_birthdate(geburtsdatum_source)
            print(f"Formatierte Patienteninformationen: {name_source}, {vorname_source}, {geburtsdatum_source_formatted}")
            geburtsdatum_formatted = file_management.format_birthdate(geburtsdatum)
            print(f"Formatierte Patienteninformationen: {name}, {vorname}, {geburtsdatum_formatted}")
            await vergleich_target_source(transfer_folder, gui, name, vorname, geburtsdatum, geburtsdatum_formatted, name_source, vorname_source, geburtsdatum_source_formatted)
        else:
            print("Keine Patienteninformationen gefunden.")
    else:
        print("Die Funktion extract_patient_info hat keine Werte zurückgegeben.")

async def vergleich_target_source(transfer_folder, gui, name, vorname, geburtsdatum, geburtsdatum_formatted, name_source, vorname_source, geburtsdatum_source_formatted):
    # Vergleiche die übergebenen Informationen mit den Quellinformationen
    print ("Vergleich wird gestartet")
    comparison_results = file_management.compare_patient_info(name, vorname, geburtsdatum_formatted, name_source, vorname_source, geburtsdatum_source_formatted)
    print(f"Vergleichsergebnisse: {comparison_results}")
    # Handeln basierend auf den Vergleichsergebnissen
    if comparison_results['is_complete_match']:
        print("Komplette Übereinstimmung der Patienteninformationen.")
    else:
        discrepancy_message = (
            f"{name}, {vorname}, * {geburtsdatum_formatted}\n\n"
            f"{name_source}, {vorname_source}, * {geburtsdatum_source_formatted}\n\n"
        )
        response = gui.show_discrepancy_dialog(discrepancy_message)
        if response is True:
            print("Benutzer hat Ja gewählt - Tomedo-Daten werden übernommen")
            gui.start_animation("Aktualisiere Patientendaten mit den Daten aus Tomedo")
            update_patient_info_in_transfer_folder(transfer_folder, name, vorname, geburtsdatum)
            gui.stop_animation()
        elif response is False:
            print("Benutzer hat Nein gewählt - Bestätigungsdialog wird angezeigt")
            # Zeige Bestätigungsdialog, ob wirklich Original-Daten behalten werden sollen
            # Übergebe die vollständigen Daten aus dem vorherigen Dialog
            tomedo_data_full = f"{name}, {vorname}, * {geburtsdatum_formatted}"
            original_data_full = f"{name_source}, {vorname_source}, * {geburtsdatum_source_formatted}"
            confirm_response = gui.show_confirm_keep_original_dialog(tomedo_data_full, original_data_full)
            if confirm_response is True:
                # Benutzer hat sich umentschieden - Tomedo-Daten verwenden
                print("Benutzer hat sich umentschieden - Tomedo-Daten werden übernommen")
                gui.start_animation("Aktualisiere Patientendaten mit den Daten aus Tomedo")
                update_patient_info_in_transfer_folder(transfer_folder, name, vorname, geburtsdatum)
                gui.stop_animation()
            elif confirm_response is False:
                print("Benutzer bestätigt - Original-Daten werden beibehalten")
                # Keine Änderung, Original-Daten bleiben erhalten
            else:
                print("Benutzer hat Bestätigungsdialog abgebrochen")
                # Abbruch - Transfer-Ordner wird bereits im Dialog gelöscht
        else:
            print("Benutzer hat Abbruch gewählt oder das Fenster geschlossen")
            # Abbruch - Transfer-Ordner wird bereits im Dialog gelöscht


