import sys
import os
import asyncio
from gui import GUI
import file_management
import threading
import dicom_processing
import shutil
import network_utils
from tkinter import filedialog
import tkinter as tk

# Konfigurationsvariablen
HOME_DIRECTORY = os.path.expanduser('~')
TRANSFER_FOLDER = os.path.join(HOME_DIRECTORY, 'Downloads/D2OTrans')
AUSGABE_DATEI = os.path.join(HOME_DIRECTORY, 't2o_modality.txt')

name = None
vorname = None
geburtsdatum = None
patienten_id = None

CONFIG_PATH = os.path.join(HOME_DIRECTORY, '.dicom2pacs.conf')

# Standardkonfigurationswerte
DEFAULT_CONFIG = {
    'server_url': 'http://192.168.188.23:8042/instances',
    'server_username': 'orthanc',
    'server_pw': 'Praxis'
}

def save_default_config():
    """Speichert die Standardkonfiguration in der Konfigurationsdatei."""
    try:
        with open(CONFIG_PATH, 'w', encoding='utf-8') as config_file:
            for key, value in DEFAULT_CONFIG.items():
                config_file.write(f'{key}={value}\n')
    except Exception as e:
        print(f"Fehler beim Speichern der Standardkonfiguration: {e}")

def load_config():
    """Lädt die Konfiguration aus der Konfigurationsdatei. Erstellt die Datei mit Standardwerten, falls nicht vorhanden."""
    config = {}
    try:
        with open(CONFIG_PATH, 'r', encoding='utf-8') as config_file:
            for line in config_file:
                line = line.strip()
                if not line or line.startswith('#'):  # Überspringe leere Zeilen und Kommentare
                    continue
                if '=' in line:
                    key, value = line.split('=', 1)
                    config[key.strip()] = value.strip()
    except FileNotFoundError:
        print("Konfigurationsdatei nicht gefunden. Erstelle eine mit Standardwerten.")
        save_default_config()
        config = DEFAULT_CONFIG.copy()  # Verwende Kopie der Standardwerte
    except Exception as e:
        print(f"Fehler beim Laden der Konfiguration: {e}")
        print("Verwende Standardwerte.")
        config = DEFAULT_CONFIG.copy()
    return config

config = load_config()
server_url = config.get('server_url')
server_username = config.get('server_username')
server_pw = config.get('server_pw')

loop = asyncio.new_event_loop()  # Initialisiere loop hier

# Erstelle den Event-Loop für asynchronen Code
def start_asyncio_loop():
    global loop  # Verweise auf die globale Variable loop
    asyncio.set_event_loop(loop)
    loop.run_forever()

asyncio_thread = threading.Thread(target=start_asyncio_loop, daemon=True)
asyncio_thread.start()

async def on_folder_selected_coro(folder_path, gui):
    print("on_folder_selected gestartet")
    await get_patientfiles(folder_path, gui)
    upload_files = file_management.get_files_in_folder(TRANSFER_FOLDER)
    if upload_files == 'no_transfer_folder':
    	results, folder_path = gui.ask_for_more("Bisher keine Bilder ausgewählt.\nAndere Orte durchsuchen?")
    	if results is False:
    		gui.on_app_close()
    	else:
    		if folder_path:
    			await get_patientfiles(folder_path, gui)
    else:
        file_paths = upload_files
        print(file_paths)
    
    if not file_paths or len(file_paths) == 0:
        gui.start_animation("Keine Dateien zum Hochladen gefunden")
        print("Keine Dateien zum Hochladen gefunden")
        gui.on_app_close()
        return
    
    if not server_url:
        gui.start_animation("FEHLER: Server-URL nicht konfiguriert")
        print("FEHLER: Server-URL nicht konfiguriert")
        gui.on_app_close()
        return
    
    availability = await network_utils.check_server_availability(server_url)
    if availability:
        print("Server ist verfügbar. Dateien werden hochgeladen.")
        # Hier wird die Funktion upload_single_file asynchron aufgerufen
        # In dicom_processing.process_dicom_files
        gui.start_animation("Lade DICOM Dateien zum PACS Server hoch")
        print(f"Starte Upload von {len(file_paths)} Dateien...")
        uploaded_count, failed_count = await network_utils.upload_multiple_files(file_paths, server_url, server_username, server_pw, gui.upload_success, gui.upload_progress)
        gui.stop_animation()
        
        if failed_count == 0:
            gui.start_animation("Bilddaten Im PACS erfolgreich eingelesen!")
            await asyncio.sleep(3)
        else:
            gui.start_animation(f"Upload abgeschlossen: {uploaded_count}/{len(file_paths)} Dateien hochgeladen")
            await asyncio.sleep(5)  # Mehr Zeit, damit Benutzer die Meldung lesen kann
        
        shutil.rmtree(TRANSFER_FOLDER)
        print(f"Transferordner {TRANSFER_FOLDER} wurde gelöscht.")
        gui.on_app_close()       
    else:
        gui.start_animation("PACS SERVER NICHT ERREICHBAR") 
        print("Server ist nicht verfügbar.")
        print("on_folder_selected abgeschlossen")  # Debugging-Ausgabe

async def get_patientfiles(folder_path, gui):
    print("Debugging-Ausgabe vor der Suche")  # Debugging-Ausgabe
    gui.hint_label.pack_forget()
    while True:
        gui.disable_browse_button()
        gui.start_animation("Suche nach DICOM Dateien")  # Starte die Suchanimation
        print(folder_path)
        files_found = file_management.find_dicom_files(folder_path)
        if files_found == 'non_found': 
            gui.stop_animation() 
            results, folder_path = gui.ask_for_more("In diesem Ordner wurde keine Bilddaten gefunden.\nAndere Orte durchsuchen?")
            if not results:  # Wenn der Benutzer 'Nein' auswählt
                break
        else:
            dicom_files, total_files = files_found
            print(dicom_files)
            gui.stop_animation()  # Erhalte Dateien und Anzahl
            print(f"Dicom-Dateien gefunden: {total_files}")
            gui.start_animation("Kopiere DICOM Dateien in den Transfer Ordner")
            await file_management.copy_dicom_files(dicom_files, folder_path, TRANSFER_FOLDER, gui.update_progress)
            gui.stop_animation()
            print(f"Dicom-Dateien wurden nach {TRANSFER_FOLDER} kopiert.")
            current_dat_folder = file_management.get_latest_dat_folder(TRANSFER_FOLDER)
            if not current_dat_folder:
                gui.stop_animation()
                gui.start_animation("FEHLER: Transferordner nicht gefunden")
                print("FEHLER: Transferordner nicht gefunden")
                break
            
            gui.start_animation("Patienten ID wird mit Tomedo ID aktualisiert")
            dicom_processing.update_patient_id_in_transfer_folder(current_dat_folder, patienten_id)
            print("ID wurde aktualisiert")
            gui.stop_animation()
            print("Erstelle Ausgabedatei")
            acq_date, modality = dicom_processing.extract_modality(current_dat_folder)
            if acq_date and modality:
                file_management.write_to_file(acq_date, modality, AUSGABE_DATEI)
            else:
                print("Warnung: Konnte Modality-Daten nicht extrahieren") 
            # Verarbeite die kopierten DICOM-Dateien synchron
            await dicom_processing.process_dicom_files(current_dat_folder, gui, name, vorname, geburtsdatum, server_url, server_username, server_pw)
            gui.stop_animation()
            gui.enable_browse_button()
            file_management.eject_cd_if_volume_path(folder_path)
            results, new_folder_path = gui.ask_for_more("Sollen mehr Bilddaten für den Patienten eingelesen werden?")
            print(f"Dialogergebnis: {results}")
            if results and new_folder_path:  # Wenn der Benutzer 'Ja' auswählt
                gui.reset_progress(total_files)
                folder_path = new_folder_path
            if not results:  # Wenn der Benutzer 'Nein' auswählt
                break

def main():
    global config, name, vorname, geburtsdatum, patienten_id
    # Argumente prüfen
    if len(sys.argv) != 5:
        print("Bitte genau vier Argumente angeben: Name, Vorname, Geburtsdatum, Patienten_ID")
        sys.exit(1)

    # Argumente zuweisen
    _, name, vorname, geburtsdatum, patienten_id = sys.argv

    print(f"Name: {name}, Vorname: {vorname}, Geburtsdatum: {geburtsdatum}, Patienten_ID: {patienten_id}")

  
    config = load_config()  # Stellen Sie sicher, dass config geladen wird, bevor GUI initiiert wird
    gui = GUI(None, TRANSFER_FOLDER, lambda: None, config)
    
    # Definiere den Callback nach der Erstellung der GUI-Instanz
    def on_folder_selected_callback(folder):
        # Plane die Coroutine im asyncio Event-Loop
        asyncio.run_coroutine_threadsafe(on_folder_selected_coro(folder, gui), loop)
    
    # Setze den Callback in der GUI-Instanz
    gui.on_folder_selected = on_folder_selected_callback
    # Funktion, die überprüft, ob eine CD eingelegt ist, und diese verarbeitet
    def check_cd_and_select():
        cd_path = file_management.check_for_cd_at_start()
        if cd_path:
            print(f"CD gefunden: {cd_path}")
            gui.root.after(100, lambda: on_folder_selected_callback(cd_path))
        else:
            print("Keine CD gefunden, bitte Ordner manuell auswählen.")
	
    # Stelle sicher, dass on_app_close als Methode der GUI-Klasse definiert ist
    gui.root.protocol("WM_DELETE_WINDOW", gui.on_app_close)
    # Überprüfe, ob eine CD eingelegt ist, bevor die GUI vollständig gestartet wird
    # Überprüfe die Einstellung und führe ggf. die CD-Überprüfung aus
    if config.get('check_for_cd', '0') == '1':
        check_cd_and_select()
    # Starte die GUI
    gui.start()

if __name__ == "__main__":
    main()