from PyQt5.QtWidgets import QDialog, QMessageBox, QDialogButtonBox, QProgressDialog, QApplication, QCompleter
from PyQt5.QtGui import QStandardItem, QStandardItemModel  # Correct import
from PyQt5.uic import loadUi
from qgis.core import QgsProject
from PyQt5.QtCore import Qt, QTimer  # Ajout de l'importation de QtCore
from PyQt5 import uic
from PyQt5.QtWidgets import *
import os
import time  # Utilisé pour simuler un traitement long
import urllib.request

# Dossier cache local
ui_cache_dir = os.path.join(os.path.expanduser("~"), "qgis_ui_cache")
os.makedirs(ui_cache_dir, exist_ok=True)

# URL de base
base_url = "https://symbols.sde03.fr/qgis/ui/"

ui_file = "action-data-reprise_luminaire-existant.ui"

ui_path = os.path.join(ui_cache_dir, ui_file)

# Télécharger si nécessaire
if not os.path.exists(ui_path):
    urllib.request.urlretrieve(base_url + ui_file, ui_path)

# Charger le UI
#uic.loadUi(local_ui_path, self)





# Définissez le chemin du fichier .ui
# ui_path = r"P:/Informatique/Cartographie/Projets QGis/Forms/action-data-reprise_luminaire-existant.ui"

def execution(iface, formulaire, data):
    try:
        # Couche de noeuds
        layer_noeuds = QgsProject.instance().mapLayersByName("Noeuds Luminaires")[0]

        # Récupérer les entités sélectionnées
        selected_features = layer_noeuds.selectedFeatures()

        if len(selected_features) != 1 :
            QMessageBox.warning(None, "Avertissement", "Cette action ne peut être réalisée que sur un seul élément !")
            return

        # Créer la fenêtre de progression
        progress = QProgressDialog("Traitement en cours...", "Annuler", 0, 100, iface.mainWindow())
        progress.setWindowModality(Qt.WindowModal)  # Utiliser Qt.WindowModal
        progress.setCancelButton(None)  # Désactiver le bouton annuler si nécessaire
        progress.setRange(0, 100)
        progress.setValue(0)
        progress.setLabelText("Mise à jour en cours...")
        progress.show()

        # Démarrer l'édition de la couche
        if not layer_noeuds.isEditable():
            layer_noeuds.startEditing()

        # Calcul de l'incrément pour la barre de progression
        increment = int(100 / len(selected_features))

        # Boucle pour traiter toutes les entités
        for feature in selected_features:
            #On fait évoluer la barre de progression
            progress.setValue(progress.value() + increment)
            QApplication.processEvents()  # Permet de garder l'interface réactive

            if feature['data'] is None:
                feature['data'] = {
                    'existant': {},
                    'nouveau': {}
                }

            existingData = feature['data']
            if 'luminaire' not in existingData['nouveau'] :
                existingData['nouveau']['luminaire'] = {}

            existingData['nouveau']['luminaire'].update(data)

            # Modifier
            feature.setAttribute('data',  existingData)

            #Validation de la modification
            layer_noeuds.updateFeature(feature)

        # Valider les modifications
        # layer_noeuds.commitChanges()

        # Désactiver la sélection
        layer_noeuds.removeSelection()

        # Fermer la fenêtre d'attente une fois le traitement terminé
        progress.setValue(100)
        progress.hide()

        # Afficher un message de confirmation
        QMessageBox.information(None, "Succès", "Le traitement est terminé avec succès !")

        # Fermer le formulaire
        formulaire.close()
        
    except Exception as e:
        QMessageBox.critical(None, "Erreur", f"Une erreur est survenue : {e}")


def formulaire(iface):
    try:
        # Créer une instance de QDialog
        dialog = QDialog()
        
        # Charger le fichier .ui dans le QDialog
        loadUi(ui_path, dialog)

        # Charger les couches nécessaires
        layer_etablissement = QgsProject.instance().mapLayersByName("Etablissements")[0]
        layer_luminaire = QgsProject.instance().mapLayersByName("Luminaires")[0]

        if not layer_etablissement  or not layer_luminaire:
            QMessageBox.critical(None, "Erreur", "Les couches nécessaires ne sont pas disponibles.")
            return

        # Définition des variables
        items_code_proprietaire_luminaire = {}
        items_code_luminaire = {}
        data = {}

        """ CODE PROPRIETAIRE LUMINAIRE """

        # Préparer l'autocomplétion pour le champ
        items_code_proprietaire_luminaire.clear()  # Vider armoires pour chaque mise à jour
        for feature in layer_etablissement.getFeatures():
            code = feature["code"]
            libelle = feature["libelle"]
            display_text = f"{code} - {libelle}" if libelle else code
            items_code_proprietaire_luminaire[display_text] = code

        completer_code_proprietaire_luminaire = QCompleter(list(items_code_proprietaire_luminaire.keys()))
        completer_code_proprietaire_luminaire.setCaseSensitivity(Qt.CaseInsensitive)
        completer_code_proprietaire_luminaire.setFilterMode(Qt.MatchContains)

        # Fonction pour gérer la sélection dans le champ
        def update_code_proprietaire_luminaire(display_text):
            # Récupération de la valeur du code
            data['code_proprietaire_luminaire'] = items_code_proprietaire_luminaire.get(dialog.nouveau_code_proprietaire_luminaire.text())
            update_luminaire_completer()
            # Donne le focus sur le champ
            dialog.nouveau_code_luminaire.setFocus()

        # Définition de la fonction qui sera exécuté quand un élément sera sélectionné
        completer_code_proprietaire_luminaire.activated.connect(update_code_proprietaire_luminaire)

        # On lie le completer au bon champ du formulaire
        dialog.nouveau_code_proprietaire_luminaire.setCompleter(completer_code_proprietaire_luminaire)

        # Ajouter un gestionnaire pour le changement de texte dans `nouveau_code_proprietaire_luminaire`
        dialog.nouveau_code_proprietaire_luminaire.textChanged.connect(lambda: (
            dialog.nouveau_code_luminaire.clear(),  # Vider le champ
            data.pop('code', None)  # Supprimer la clé de `data`
        ))


        """ CODE LUMINAIRE """

        # Préparer l'autocomplétion pour le champ `nouveau_code_luminaire`
        def update_luminaire_completer():
            items_code_luminaire.clear()  # Vider le tableau pour chaque mise à jour
            for feature in layer_luminaire.getFeatures():
                if feature["code_proprietaire"] == data['code_proprietaire_luminaire'] :
                    code = feature["code"]
                    libelle = feature["libelle_reference_luminaire"]
                    display_text = f"{code} - {libelle}" if libelle else code
                    items_code_luminaire[display_text] = code

            completer_code_luminaire = QCompleter(list(items_code_luminaire.keys()))
            completer_code_luminaire.setCaseSensitivity(Qt.CaseInsensitive)
            completer_code_luminaire.setFilterMode(Qt.MatchContains)

            # Fonction pour gérer la sélection dans le champ
            def update_code_luminaire(display_text):
                # Récupération de la valeur du code
                data['code'] = items_code_luminaire.get(dialog.nouveau_code_luminaire.text())

            # Définition de la fonction qui sera exécuté quand un élément sera sélectionné
            completer_code_luminaire.activated.connect(update_code_luminaire)

            # On lie le completer au bon champ du formulaire
            dialog.nouveau_code_luminaire.setCompleter(completer_code_luminaire)


        """ GESTION DES BOUTONS """

        # Gérer les boutons
        button_box = dialog.findChild(QDialogButtonBox, "buttonBox")

        if button_box:
            def on_accept():
                # Vérifier si le code_armoire est vide
                if 'code_proprietaire_luminaire' not in data or data['code_proprietaire_luminaire'] == '':
                    QMessageBox.warning(None, "Saisie incomplète", "Il faut définir un proprietaire de luminaire")
                    return

                # Vérifier si le code_départ est vide
                if 'code' not in data or data['code'] == '':
                    QMessageBox.warning(None, "Saisie incomplète", "Il faut définir un luminaire")
                    return

                # On exécute le traitement en renvoyant les datas
                execution(iface, dialog, data)

            # Connecter le bouton "OK"
            button_box.accepted.disconnect()  # Supprimer la connexion pour empecher la fermeture automatique du formulaire
            button_box.accepted.connect(on_accept)  # Connecter le gestionnaire à la place
            button_box.rejected.connect(dialog.reject)

        dialog.exec_()

    except Exception as e:
        # Gérer les erreurs
        QMessageBox.critical(None, "Erreur", f"Impossible d'ouvrir le formulaire : {e}")
