from PyQt5 import uic
from PyQt5.QtWidgets import QDialog, QMessageBox, QLineEdit, QCompleter, QComboBox
from PyQt5.QtGui import QStandardItem, QStandardItemModel  # Correct import
from PyQt5.QtCore import QStringListModel, Qt
import os
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 = "luminaire.ui"

local_ui_path = os.path.join(ui_cache_dir, ui_file)

# Télécharger si nécessaire
if not os.path.exists(local_ui_path):
    urllib.request.urlretrieve(base_url + ui_file, local_ui_path)

# Charger le UI
uic.loadUi(local_ui_path, self)

class MonFormulaire(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
       

        # Définir les champs
        self.code_proprietaire_armoire_field = self.findChild(QLineEdit, "code_proprietaire_armoire")
        self.code_armoire_field = self.findChild(QLineEdit, "code_armoire")
        self.code_depart_field = self.findChild(QComboBox, "code_depart")

        # Récupérer la couche Etablissements
        layer_etablissements = QgsProject.instance().mapLayersByName("Etablissements")[0]
        if not layer_etablissements:
            print("La couche 'Etablissements' n'a pas été trouvée.")
            return
        else:
            print(f"Nombre d'entités dans la couche 'Etablissements' : {layer_etablissements.featureCount()}")

        # Créer un modèle pour le QCompleter
        completer_model = QStandardItemModel()

        # Itérer sur les entités de la couche pour remplir le modèle
        for feature in layer_etablissements.getFeatures():
            # Extraire le code et le libellé depuis la couche
            code = feature["code"]  # Assurez-vous que le nom du champ est correct
            libelle = feature["libelle"]  # Idem ici

            # Créer un item avec le libellé pour l'affichage
            item = QStandardItem(libelle)
            # Stocker le code dans les données de l'item
            item.setData(code, Qt.UserRole)

            # Ajouter l'item au modèle
            completer_model.appendRow(item)


        # Configurer le QCompleter pour le champ "code_proprietaire_armoire"
        self.code_proprietaire_armoire_completer = QCompleter()
        self.code_proprietaire_armoire_completer.setModel(completer_model)
        # self.code_proprietaire_completer = QCompleter(completer_model)
        self.code_proprietaire_armoire_completer.setCompletionMode(QCompleter.PopupCompletion)
        self.code_proprietaire_armoire_completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.code_proprietaire_armoire_completer.setFilterMode(Qt.MatchContains)
        
        # Associer le modèle au champ de texte
        self.code_proprietaire_armoire_field.setCompleter(self.code_proprietaire_armoire_completer)

        # Mise à jour explicite du champ de texte
        # self.code_proprietaire_armoire_field.update()

        # Connecter le signal 'activated' pour traiter la sélection
        self.code_proprietaire_armoire_completer.activated.connect(self.filtrer_armoires_par_code_proprietaire)

        # Initialiser le completer pour le champ "code_armoire"
        self.code_armoire_completer = QCompleter()
        self.code_armoire_completer.setCompletionMode(QCompleter.PopupCompletion)
        self.code_armoire_completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.code_armoire_completer.setFilterMode(Qt.MatchContains)
        self.code_armoire_field.setCompleter(self.code_armoire_completer)

        print("QCompleter initialisé avec succès.")
    
    def filtrer_armoires_par_code_proprietaire(self, selected):
        """
        Filtre les codes d'armoires en fonction de la sélection effectuée
        dans 'code_proprietaire_armoire_field' et met à jour le completer
        du champ 'code_armoire_field'.
        """
        # Lorsque l'utilisateur sélectionne un libellé dans le completer
        model = self.code_proprietaire_armoire_completer.completionModel()
        index = self.code_proprietaire_armoire_completer.popup().currentIndex()

        # Extraire le code associé au libellé sélectionné
        self.code_proprietaire_armoire = model.data(index, Qt.UserRole)

        try:
            # Récupérer la couche 'Armoires'
            layer_armoires = QgsProject.instance().mapLayersByName("Armoires")[0]
            
            # Filtrer les entités en fonction du champ 'code_proprietaire'
            index_code_proprietaire = layer_armoires.fields().indexOf("code_proprietaire")
            index_code_armoire = layer_armoires.fields().indexOf("code")

            # Vérifier que les index sont valides
            if index_code_proprietaire == -1 or index_code_armoire == -1:
                raise ValueError("Champs 'code_proprietaire' ou 'code' non trouvés dans la couche 'Armoires'.")

            # Obtenir les valeurs des entités correspondant au texte sélectionné
            valeurs_filtrees = [
                str(feature[index_code_armoire])
                for feature in layer_armoires.getFeatures()
                if str(feature[index_code_proprietaire]).lower() == self.code_proprietaire_armoire.lower()
            ]

            # Mettre à jour le modèle de l'autocomplétion pour 'code_armoire_field'
            completer_model = QStringListModel()
            completer_model.setStringList(valeurs_filtrees)
            self.code_armoire_completer.setModel(completer_model)

            # Mettre le focus sur le champ `code_armoire` (optionnel pour améliorer l'expérience utilisateur)
            self.code_armoire_field.setFocus()
            
            # Initialiser le completer pour le champ "code_depart"
            self.code_depart_completer = QCompleter()
            self.code_depart_completer.setCompletionMode(QCompleter.PopupCompletion)
            self.code_depart_completer.setCaseSensitivity(Qt.CaseInsensitive)
            self.code_depart_completer.setFilterMode(Qt.MatchContains)
            self.code_depart_field.setCompleter(self.code_depart_completer)

            # Connecter le signal 'activated' pour traiter la sélection
            self.code_armoire_completer.activated.connect(self.filtrer_departs_par_code_proprietaire_armoire_and_code_armoire)
            
        except Exception as e:
            # Afficher un message d'erreur en cas de problème
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(f"Erreur lors du filtrage : {str(e)}")
            msg.setWindowTitle("Erreur")
            msg.exec_()

    def filtrer_departs_par_code_proprietaire_armoire_and_code_armoire(self, selected):
        # Extraire le code associé au libellé sélectionné
        self.code_armoire = selected

        try:
            # Récupérer la couche 'Départs'
            layer_departs = QgsProject.instance().mapLayersByName("Départs")[0]

            # Filtrer les entités en fonction du champ 'code_proprietaire'
            index_code_proprietaire_armoire = layer_departs.fields().indexOf("code_proprietaire_armoire")
            index_code_armoire = layer_departs.fields().indexOf("code_armoire")
            index_code_depart = layer_departs.fields().indexOf("code")

            for feature in layer_departs.getFeatures():
                if (str(feature[index_code_proprietaire_armoire]).lower() == self.code_proprietaire_armoire.lower() and
                    str(feature[index_code_armoire]).lower() == self.code_armoire.lower()):
                    # Ajouter l'élément au QComboBox
                    self.code_depart_field.addItem(str(feature[index_code_depart]))

            # Mettre le focus sur le champ `code_armoire` (optionnel pour améliorer l'expérience utilisateur)
            self.code_depart_field.setFocus()

            # Connecter le signal 'activated' pour traiter la sélection
            self.code_depart_field.currentIndexChanged.connect(self.set_code_depart)

            # Appeler la fonction manuellement après le chargement des items
            self.set_code_depart()
            
        except Exception as e:
            # Afficher un message d'erreur en cas de problème
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText(f"Erreur lors du filtrage : {str(e)}")
            msg.setWindowTitle("Erreur")
            msg.exec_()

    def set_code_depart(self):
        # Vérifier que le combobox contient au moins un élément
        if self.code_depart_field.count() > 0:
            # Récupérer la valeur sélectionnée (le texte dans le combobox)
            self.code_depart = self.code_depart_field.currentText()
        else:
            self.code_depart = None


def afficher_formulaire():
    try:
        # Crée l'instance du formulaire
        formulaire = MonFormulaire()  

        # Affiche le formulaire
        formulaire.exec_()

        #Couche luminaire
        layer_luminaires = QgsProject.instance().mapLayersByName("Luminaires")[0]

        # Récupérer les entités sélectionnées
        selected_features = layer_luminaires.selectedFeatures()

        # Boucle pour traiter toutes les entités
        for feature in selected_features:
            # Modifier
            feature.setAttribute('code_proprietaire_armoire', formulaire.code_proprietaire_armoire)
            feature.setAttribute('code_armoire', formulaire.code_armoire)
            feature.setAttribute('code_depart', formulaire.code_depart)

            print(feature)

            #Validation de la modification
            layer_luminaires.updateFeature(feature)

        

    except Exception as e:
        # Gestion des erreurs si le formulaire ne peut pas être chargé
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setText("Impossible de charger le formulaire: " + str(e))
        msg.setWindowTitle("Erreur")
        msg.exec_()

# Récupère le champ `QLineEdit` du formulaire
def setup_autocomplete(field, model):
    # Initialise le QCompleter avec les valeurs uniques
    completer = QCompleter()
    completer.setModel(model)
    completer.setCompletionMode(QCompleter.PopupCompletion)
    completer.setCaseSensitivity(Qt.CaseInsensitive)
    completer.setFilterMode(Qt.MatchContains)
    field.setCompleter(completer)

# Appeler la fonction pour afficher le formulaire
afficher_formulaire()
