from PySide6.QtWidgets import QDialog, QMessageBox, QApplication
from PySide6.QtCore import QThread, Signal, Qt

from ui.PostgreSqlConfigDialog_ui import Ui_PostgreSqlConfigDialog


class DatabaseTestThread(QThread):
    """Thread für den Datenbankverbindungstest."""

    # Signale für die Kommunikation mit dem UI-Thread
    test_completed = Signal(bool, str)  # success, message

    def __init__(self, connection_data):
        super().__init__()
        self.connection_data = connection_data

    def run(self):
        """Führt den Datenbanktest in einem separaten Thread aus."""
        import polars as pl
        try:
            timeout = self.connection_data.get("timeout", 10)
            uri = (
                f"postgresql://{self.connection_data['username']}:{self.connection_data['password']}"
                f"@{self.connection_data['host']}:{self.connection_data['port']}"
                f"/{self.connection_data['database']}"
                f"?connect_timeout={timeout}"
            )

            # Datenbankverbindung testen
            r = pl.read_database_uri(
                query="SELECT 1",
                uri=uri
            )
            
            # Erfolg signalisieren
            self.test_completed.emit(True, f"Verbindung erfolgreich:\n{str(r)}")
            
        except Exception as e:
            # Fehler signalisieren
            self.test_completed.emit(False, f"Verbindung fehlgeschlagen:\n{str(e)}")


class PostgreSqlConfigDialog(QDialog):
    """Dialog zur Konfiguration einer PostgreSQL-Datenbank ohne ID."""

    def __init__(self, parent=None):
        super().__init__(parent)

        # UI einrichten
        self.ui = Ui_PostgreSqlConfigDialog()
        self.ui.setupUi(self)

        # SSL-Modus auf "prefer" setzen (Standard)
        self.ui.sslModeComboBox.setCurrentText("prefer")

        # Thread für Datenbanktest
        self.test_thread = None

        # Signale verbinden
        self.ui.testConnectionButton.clicked.connect(self.test_connection)

    def test_connection(self):
        """Testet die Datenbankverbindung in einem separaten Thread."""
        data = self.get_data()
        if not data:
            QMessageBox.warning(self, "Verbindungstest", "Bitte füllen Sie alle erforderlichen Felder aus.")
            return

        # Button deaktivieren und Text mit Sanduhrsymbol ändern
        self.ui.testConnectionButton.setEnabled(False)
        original_text = self.ui.testConnectionButton.text()
        self.ui.testConnectionButton.setText("⏳ Teste Verbindung...")
        
        # Wartecursor setzen
        QApplication.setOverrideCursor(Qt.WaitCursor)

        # Thread erstellen und starten
        self.test_thread = DatabaseTestThread(data)
        self.test_thread.test_completed.connect(self.on_test_completed)
        self.test_thread.finished.connect(lambda: self.cleanup_test(original_text))
        self.test_thread.start()

    def on_test_completed(self, success, message):
        """Wird aufgerufen, wenn der Datenbanktest abgeschlossen ist."""
        if success:
            QMessageBox.information(self, "Verbindungstest", message)
        else:
            QMessageBox.warning(self, "Verbindungstest", message)

    def cleanup_test(self, original_text):
        """Räumt nach dem Test auf."""
        # Wartecursor entfernen
        QApplication.restoreOverrideCursor()
        
        # Button wieder aktivieren und ursprünglichen Text wiederherstellen
        self.ui.testConnectionButton.setEnabled(True)
        self.ui.testConnectionButton.setText(original_text)
        
        # Thread-Referenz löschen
        if self.test_thread:
            self.test_thread.deleteLater()
            self.test_thread = None

    def set_data(self, data):
        """Setzt die Daten in den Dialog."""
        if data:
            self.ui.nameEdit.setText(data.get("name", ""))
            self.ui.hostEdit.setText(data.get("host", "localhost"))
            self.ui.portSpinBox.setValue(data.get("port", 5432))
            self.ui.databaseEdit.setText(data.get("database", ""))
            self.ui.usernameEdit.setText(data.get("username", ""))
            self.ui.passwordEdit.setText(data.get("password", ""))
            self.ui.sslModeComboBox.setCurrentText(data.get("ssl_mode", "prefer"))
            self.ui.timeoutSpinBox.setValue(data.get("timeout", 10))

    def get_data(self):
        """Gibt die eingegebenen Daten zurück."""
        if not self.ui.nameEdit.text().strip():
            return None
        if not self.ui.hostEdit.text().strip():
            return None
        if not self.ui.databaseEdit.text().strip():
            return None
        if not self.ui.usernameEdit.text().strip():
            return None

        return {
            "name": self.ui.nameEdit.text().strip(),
            "host": self.ui.hostEdit.text().strip(),
            "port": self.ui.portSpinBox.value(),
            "database": self.ui.databaseEdit.text().strip(),
            "username": self.ui.usernameEdit.text().strip(),
            "password": self.ui.passwordEdit.text(),  # Passwort kann leer sein
            "ssl_mode": self.ui.sslModeComboBox.currentText(),
            "timeout": self.ui.timeoutSpinBox.value(),
        }
