# -*- coding: utf-8 -*-
"""
/***************************************************************************
 QUtility
                                 A QGIS plugin
 Un toolbox multifunzione per QGIS: rinomina layer, cambia tipi di campo, importa shapefile da ZIP e altro ancora, tutto in pochi clic.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2025-05-06
        git sha              : $Format:%H$
        copyright            : (C) 2025 by Lorenzo Alunni
        email                : gis@eagleprojects.it
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication, Qt # type: ignore
from qgis.PyQt.QtGui import QIcon # type: ignore
from qgis.PyQt.QtWidgets import QAction, QMessageBox # type: ignore
from qgis.core import (QgsMessageLog, Qgis, QgsMapLayer, QgsWkbTypes, 
                       QgsCoordinateReferenceSystem, QgsCoordinateTransform, 
                       QgsProject, QgsProcessingContext, QgsProcessingFeedback, QgsWkbTypes,
                       QgsVectorLayer, QgsFeatureRequest) # type: ignore

# Initialize Qt resources from file resources.py
from .resources import *
from .resources_rc import *
# Import the code for the dialog
from .qutility_dialog import QUtilityDialog
from .batch_merger import BatchMergerAlgorithm, run_batch_merger
import os.path
import time


class QUtility:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QUtility_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&QUtility')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('QUtility', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        status_tip,
        whats_this,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        # Pulisci le azioni esistenti prima di crearne di nuove
        # Questo previene le icone duplicate durante i ricaricamenti del plugin
        if self.actions:
            for action in self.actions:
                try:
                    self.iface.removePluginMenu(self.tr(u'&QUtility'), action)
                    self.iface.removeToolBarIcon(action)
                except:
                    # Ignora errori se l'azione non esiste più
                    pass
            self.actions.clear()

        icon_path = ':/plugins/qutility/icon.png'

        # Crea un'istanza dell'icona da usare ovunque
        self.plugin_icon = QIcon(icon_path)

        self.add_action(
            icon_path,
            text=self.tr(u'QUtility'),
            callback=self.run,
            status_tip=self.tr(u'A multi-function toolbox for QGIS'),
            whats_this=self.tr(u'A multi-function toolbox for QGIS'),
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True

        from qgis.core import QgsApplication # type: ignore
        QgsApplication.instance().processEvents()

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&QUtility'),
                action)
            self.iface.removeToolBarIcon(action)


    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = QUtilityDialog()

            # Get version from metadata.txt file
            metadata_file = os.path.join(self.plugin_dir, 'metadata.txt')
            plugin_version = 'N/A'

            try:
                import configparser
                config = configparser.ConfigParser()
                config.read(metadata_file)
                plugin_version = config['general']['version']
            except (KeyError, configparser.Error, FileNotFoundError):
                plugin_version = 'N/A'

            qgis_version = Qgis.QGIS_VERSION
            self.dlg.labelPluginVersion.setText(f"Plugin version: {plugin_version}")
            self.dlg.labelQgisVersion.setText(f"QGIS version: {qgis_version}")

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass

    def run_overlaps_counter(self):
        """Esegue lo script processing per Overlaps Counter"""

        from qgis.PyQt.QtWidgets import QApplication
        QApplication.setOverrideCursor(Qt.WaitCursor)
        QApplication.processEvents()

        try:
            
            start_time = time.time()
            
            # Recupera i layer selezionati dai combobox
            layer1 = self.dlg.lyr1_oc.currentLayer()  # Layer su cui fare il conteggio
            layer2 = self.dlg.lyr2_oc.currentLayer()  # Layer sovrapposto da conteggiare
            
            # Verifica che tutti i layer necessari siano selezionati
            if not all([layer1, layer2]):
                QMessageBox.warning(
                    self.dlg,
                    "Error",
                    "Select both required layers before proceeding"
                )
                return
            
            # Log tipo di script utilizzato
            geom_type_layer1 = QgsWkbTypes.geometryType(layer1.wkbType())
            QgsMessageLog.logMessage(
                f"Using script: overlaps_counter_line "
                f"for geometry type: {QgsWkbTypes.geometryDisplayString(geom_type_layer1)}",
                "QUtility", Qgis.Info
            )
            
            # Controllo CRS
            crs1 = layer1.crs()
            crs2 = layer2.crs()
            if crs1 != crs2:
                QMessageBox.warning(
                    self.dlg, "Warning",
                    "The two layers have different CRS:\n\n"
                    f"{layer1.name()}: {crs1.authid()} ({crs1.description()})\n"
                    f"{layer2.name()}: {crs2.authid()} ({crs2.description()})\n\n"
                    "Please align them before proceeding."
                )
                return
            QgsMessageLog.logMessage(f"CRS validation passed: {crs1.authid()}", "QUtility", Qgis.Info)
            
            # Recupera il percorso del file di output
            output_path = self.dlg.cartout_oc.filePath()
            
            # Verifica che il percorso di output sia selezionato
            if not output_path:
                QMessageBox.warning(
                    self.dlg,
                    "Warning",
                    "Select output file before proceeding"
                )
                return
            
            # Rimuovi dal progetto eventuale layer già caricato con la stessa source
            for lyr in list(QgsProject.instance().mapLayers().values()):
                try:
                    src = getattr(lyr, "source", None)
                    if callable(src):
                        src = lyr.source()
                    if src:
                        base_src = src.split("|")[0]
                        if os.path.normpath(base_src) == os.path.normpath(output_path):
                            QgsProject.instance().removeMapLayer(lyr.id())
                            QgsMessageLog.logMessage(
                                f"Removed existing layer from project: {base_src}",
                                "QUtility", Qgis.Info
                            )
                except Exception as e:
                    QgsMessageLog.logMessage(f"Layer removal check error: {e}", "QUtility", Qgis.Warning)
            
            # Se è uno SHP, cancella shapefile + sidecar; altrimenti cancella il file singolo (es. gpkg)
            if output_path.lower().endswith(".shp"):
                base = os.path.splitext(output_path)[0]
                for ext in [".shp", ".shx", ".dbf", ".prj", ".cpg", ".qpj"]:
                    f = base + ext
                    if os.path.exists(f):
                        os.remove(f)
                        QgsMessageLog.logMessage(f"Deleted old file: {f}", "QUtility", Qgis.Info)
            else:
                if os.path.exists(output_path):
                    os.remove(output_path)
                    QgsMessageLog.logMessage(f"Deleted old file: {output_path}", "QUtility", Qgis.Info)
            
            # Determina se usare solo gli elementi selezionati
            use_selected_layer1 = self.dlg.ckbox_lyr1_oc.isChecked() and self.dlg.ckbox_lyr1_oc.isEnabled()
            use_selected_layer2 = self.dlg.ckbox_lyr2_oc.isChecked() and self.dlg.ckbox_lyr2_oc.isEnabled()
            
            QgsMessageLog.logMessage(
                f"use_sel1={use_selected_layer1}, use_sel2={use_selected_layer2}",
                "QUtility", Qgis.Info
            )
            
            # Verifica che ci siano elementi da processare se si usano le selezioni
            if use_selected_layer1 and layer1.selectedFeatureCount() == 0:
                QMessageBox.warning(
                    self.dlg,
                    "Error", 
                    f"The layer '{layer1.name()}' has no selected features"
                )
                return
                
            if use_selected_layer2 and layer2.selectedFeatureCount() == 0:
                QMessageBox.warning(
                    self.dlg,
                    "Error", 
                    f"The layer '{layer2.name()}' has no selected features"
                )
                return
            
            # Prepara i layer di input considerando le selezioni
            input_layer1 = layer1
            input_layer2 = layer2
            
            # Se ci sono selezioni attive, crea layer temporanei con solo le features selezionate
            if use_selected_layer1:
                QgsMessageLog.logMessage("Saving selected features of layer1 to temporary file", "QUtility", Qgis.Info)
                # Crea un layer temporaneo con solo gli elementi selezionati
                selected_features1 = layer1.selectedFeatures()
                temp_layer1 = QgsVectorLayer(f"LineString?crs={layer1.crs().authid()}", 
                                        f"{layer1.name()}_selected", "memory")
                temp_layer1.dataProvider().addAttributes(layer1.fields())
                temp_layer1.updateFields()
                temp_layer1.dataProvider().addFeatures(selected_features1)
                input_layer1 = temp_layer1
                QgsMessageLog.logMessage(f"Temp layer1 saved: {input_layer1.featureCount()} features", "QUtility", Qgis.Info)
                
            if use_selected_layer2:
                QgsMessageLog.logMessage("Saving selected features of layer2 to temporary file", "QUtility", Qgis.Info)
                # Crea un layer temporaneo con solo gli elementi selezionati  
                selected_features2 = layer2.selectedFeatures()
                temp_layer2 = QgsVectorLayer(f"LineString?crs={layer2.crs().authid()}", 
                                        f"{layer2.name()}_selected", "memory")
                temp_layer2.dataProvider().addAttributes(layer2.fields())
                temp_layer2.updateFields()
                temp_layer2.dataProvider().addFeatures(selected_features2)
                input_layer2 = temp_layer2
                QgsMessageLog.logMessage(f"Temp layer2 saved: {input_layer2.featureCount()} features", "QUtility", Qgis.Info)
            
            QgsMessageLog.logMessage(f"Temporary layers: Layer1={input_layer1.name()}, Layer2={input_layer2.name()}", "QUtility", Qgis.Info)
            
            # Importa e istanzia direttamente l'algoritmo
            from .overlaps_counter_line import Num_cavi_su_infrastruttua
            algorithm = Num_cavi_su_infrastruttua()
            
            # Prepara i parametri per lo script processing
            parameters = {
                'infrastruttura_4326': input_layer1,  # Layer su cui fare il conteggio
                'cavi_4326': input_layer2,            # Layer sovrapposto da conteggiare
                'InfrastrutturaConNcavi': output_path
            }
            
            # Esegui lo script processing
            QgsMessageLog.logMessage(
                "Starting Overlaps Counter processing...", 
                "QUtility", 
                Qgis.Info
            )
            
            # Esegui il processing direttamente
            context = QgsProcessingContext()
            context.setProject(QgsProject.instance())
            feedback = QgsProcessingFeedback()
            
            # Debug pre-run
            def _dbg_layer_info(lbl, lyr):
                return (f"\n              {lbl}:\n"
                        f"\n              - Name: {lyr.name()}"
                        f"\n              - Valid: {lyr.isValid()}"
                        f"\n              - Source: {lyr.source()}"
                        f"\n              - CRS: {lyr.crs().authid()}"
                        f"\n              - Feature count: {lyr.featureCount()}"
                        f"\n              - Geometry type: {QgsWkbTypes.geometryDisplayString(QgsWkbTypes.geometryType(lyr.wkbType()))}")
            QgsMessageLog.logMessage("🔍 COMPLETE DEBUG BEFORE PROCESSING:" + _dbg_layer_info("input_layer1", input_layer1)
                                    + _dbg_layer_info("input_layer2", input_layer2), "QUtility", Qgis.Info)
            
            # Geometrie invalide (solo log)
            inv1 = sum(1 for f in input_layer1.getFeatures() if not f.geometry() or f.geometry().isNull())
            inv2 = sum(1 for f in input_layer2.getFeatures() if not f.geometry() or f.geometry().isNull())
            QgsMessageLog.logMessage(f"Invalid geometries: Layer1={inv1}, Layer2={inv2}", "QUtility", Qgis.Info)
            
            # Esegui l'algoritmo
            results = algorithm.processAlgorithm(parameters, context, feedback)
            
            # Verifica file di output
            QgsMessageLog.logMessage("🔍 Checking output file...", "QUtility", Qgis.Info)
            QgsMessageLog.logMessage(f"   Expected path: {output_path}", "QUtility", Qgis.Info)
            QgsMessageLog.logMessage(f"   File exists: {os.path.exists(output_path)}", "QUtility", Qgis.Info)
            
            # Carica il layer risultante nel progetto QGIS
            if results and os.path.exists(output_path):
                layer_name = f"Overlaps_Count_{layer1.name()}"
                output_layer = QgsVectorLayer(output_path, layer_name, "ogr")
                QgsMessageLog.logMessage(f"   Test layer valid: {output_layer.isValid()}", "QUtility", Qgis.Info)
                
                if output_layer.isValid():
                    QgsProject.instance().addMapLayer(output_layer)
                    n_feat = output_layer.featureCount()
                    QgsMessageLog.logMessage(f"✅ Layer loaded: {layer_name} with {n_feat} features", "QUtility", Qgis.Info)
                    
                    # Calcola statistiche sui risultati
                    total_features = output_layer.featureCount()
                    overlaps_field = 'n_overlaps'
                    
                    features_with_overlaps = 0
                    max_overlaps = 0
                    total_overlaps = 0
                    
                    try:
                        # Verifica che il campo n_overlaps esista
                        field_names = [f.name() for f in output_layer.fields()]
                        if overlaps_field in field_names:
                            for feature in output_layer.getFeatures():
                                n_overlaps = feature[overlaps_field]
                                if n_overlaps and n_overlaps > 0:
                                    features_with_overlaps += 1
                                    total_overlaps += n_overlaps
                                    max_overlaps = max(max_overlaps, n_overlaps)
                        else:
                            # Se il campo non esiste, cerca campi simili
                            overlaps_candidates = [f for f in field_names if 'overlap' in f.lower() or 'count' in f.lower()]
                            if overlaps_candidates:
                                overlaps_field = overlaps_candidates[0]
                                for feature in output_layer.getFeatures():
                                    n_overlaps = feature[overlaps_field]
                                    if n_overlaps and n_overlaps > 0:
                                        features_with_overlaps += 1
                                        total_overlaps += n_overlaps
                                        max_overlaps = max(max_overlaps, n_overlaps)
                                        
                        QgsMessageLog.logMessage(f"Statistics: {total_features} total features, {features_with_overlaps} with overlaps", "QUtility", Qgis.Info)
                        
                    except Exception as stats_error:
                        QgsMessageLog.logMessage(f"An error occurred while calculating the statistics: {str(stats_error)}", "QUtility", Qgis.Warning)
                        features_with_overlaps = "N/A"
                        max_overlaps = "N/A"
                        total_overlaps = "N/A"
                else:
                    QgsMessageLog.logMessage("⚠️ Output layer is NOT valid.", "QUtility", Qgis.Warning)
            else:
                QgsMessageLog.logMessage("⚠️ Output file NOT FOUND or empty results.", "QUtility", Qgis.Warning)
            
            # Calcola il tempo di esecuzione
            elapsed = time.time() - start_time
            QgsMessageLog.logMessage(f"✅ END PROCESSING in {elapsed:.2f}s", "QUtility", Qgis.Info)
            
            minutes = int(elapsed // 60)
            seconds = elapsed % 60
            if minutes > 0:
                QgsMessageLog.logMessage(f"⏱️ Processing completed in {minutes} minutes and {seconds:.2f} seconds", "QUtility", Qgis.Info)
            else:
                QgsMessageLog.logMessage(f"⏱️ Processing completed in {seconds:.2f} seconds", "QUtility", Qgis.Info)

            # Mostra popup di successo
            success_message = "Overlaps Counter processing completed successfully!\n\n"
            
            QMessageBox.information(self.dlg, "Success", success_message)
            
        except Exception as e:
            QgsMessageLog.logMessage(f"❌ ERROR in run_overlaps_counter: {e}", "QUtility", Qgis.Critical)
            self.iface.messageBar().pushCritical(
                "Error", 
                f"An error occurred during the execution of Overlaps Counter: {str(e)}"
            )
            QMessageBox.critical(self.dlg, "Error", f"Overlaps Counter failed:\n{e}")

        finally:
            QApplication.restoreOverrideCursor()

    def run_batch_merger(self):
        """Esegue lo script processing per Batch Merger con layer temporaneo in memoria"""
        try:
            import time
            import processing
            from qgis.core import QgsMessageLog, Qgis, QgsProject, QgsVectorLayer
            from PyQt5.QtWidgets import QMessageBox
            
            start_time = time.time()
            
            # RECUPERA PARAMETRI DALL'INTERFACCIA
            selected_layers = self.dlg.get_selected_batch_merger_layers()
            target_crs = self.dlg.get_batch_merger_target_crs()
            add_fields = self.dlg.get_batch_merger_add_fields()

            # VALIDAZIONI E POPUP
            if len(selected_layers) < 2:
                QMessageBox.warning(self.dlg, "Warning", "Please select at least two layers having the same geometry type and file extension.")
                return
            
            if not target_crs.isValid():
                QMessageBox.warning(self.dlg, "Warning", "Please select a valid coordinate reference system")
                return
            
            # Controllo tipi di geometria
            geometry_types = set()
            for layer in selected_layers:
                if isinstance(layer, QgsVectorLayer):
                    geometry_types.add(layer.geometryType())

            # Se ci sono geometrie diverse, mostra avvertimento
            if len(geometry_types) > 1:
                QMessageBox.warning(self.dlg, "Warning", "The selected layers have different geometry type.")
                return
            
            # Controllo formati diversi
            source_extensions = set()
            ext_details = []
            
            for layer in selected_layers:
                layer_source = layer.source()
                if "|" in layer_source:
                    layer_source = layer_source.split("|")[0]
                
                file_extension = layer_source.split(".")[-1].lower() if "." in layer_source else "unknown"
                source_extensions.add(file_extension)
                ext_details.append(f"• {layer.name()}: .{file_extension}")
            
            if len(source_extensions) > 1:
                extensions_list = ", ".join(f".{ext}" for ext in sorted(source_extensions))
                
                warning_message = f"""The selected layers have different file extensions:

{chr(10).join(ext_details)}

Detected formats: {extensions_list}

Cannot merge layers with different file formats.
Please select layers with the same format."""
                
                QMessageBox.critical(self.dlg, "Different File Formats", warning_message)
                QgsMessageLog.logMessage("Batch Merger cancelled: mixed file formats not supported", "QUtility", Qgis.Warning)
                return
            
            # LOGGING INIZIALE
            QgsMessageLog.logMessage(f"🚀 Starting Batch Merger with {len(selected_layers)} layers", "QUtility", Qgis.Info)
            
            # **MERGE DIRETTO CON OUTPUT IN MEMORIA**
            merge_params = {
                'LAYERS': selected_layers,
                'CRS': target_crs,
                'OUTPUT': 'memory:'
            }
            
            merge_result = processing.run("native:mergevectorlayers", merge_params)
            merged_layer = merge_result['OUTPUT']

            # Stampa di debug
            print(f"🔍 DEBUG: add_fields = {add_fields}")
            print(f"🔍 DEBUG: not add_fields = {not add_fields}")
            print(f"🔍 DEBUG: merged_layer.isValid() = {merged_layer.isValid()}")

            # **RIMUOVI CAMPI "layer" E "path" SE NECESSARIO**
            if not add_fields and merged_layer.isValid():
                print("✅ ENTRATO nella condizione di rimozione campi")  # ←← AGGIUNGI QUESTO
                QgsMessageLog.logMessage("🗑️ Removing 'layer' and 'path' fields...", "QUtility", Qgis.Info)
                # ... resto del codice
            else:
                print("❌ NON ENTRATO nella condizione di rimozione campi")  # ←← AGGIUNGI QUESTO
            
            # **RIMUOVI CAMPI "layer" E "path" SE NECESSARIO**
            if not add_fields and merged_layer.isValid():
                QgsMessageLog.logMessage("🗑️ Removing 'layer' and 'path' fields...", "QUtility", Qgis.Info)
                
                fields_to_remove = []
                field_names_to_remove = []
                
                for field in merged_layer.fields():
                    if field.name().lower() in ['layer', 'path']:
                        field_index = merged_layer.fields().indexOf(field.name())
                        fields_to_remove.append(field_index)
                        field_names_to_remove.append(field.name())
                
                if fields_to_remove:
                    QgsMessageLog.logMessage(f"🔧 Found fields to remove: {field_names_to_remove}", "QUtility", Qgis.Info)
                    
                    # **SOLUZIONE ALTERNATIVA: Rimozione manuale dei campi**
                    try:
                        QgsMessageLog.logMessage("🔧 Removing fields manually...", "QUtility", Qgis.Info)
                        
                        # Entra in modalità editing
                        merged_layer.startEditing()
                        
                        # Rimuovi i campi uno per uno (dal più alto al più basso per evitare problemi di indice)
                        fields_to_remove_sorted = sorted(fields_to_remove, reverse=True)
                        
                        for field_index in fields_to_remove_sorted:
                            success = merged_layer.deleteAttribute(field_index)
                            QgsMessageLog.logMessage(f"🗑️ Field index {field_index}: {'removed' if success else 'FAILED'}", "QUtility", Qgis.Info)
                        
                        # Aggiorna i campi e salva
                        merged_layer.updateFields()
                        merged_layer.commitChanges()
                        
                        # Verifica finale
                        final_fields = [field.name() for field in merged_layer.fields()]
                        QgsMessageLog.logMessage(f"🔍 DEBUG: Campi finali dopo rimozione manuale = {final_fields}", "QUtility", Qgis.Info)
                        
                        # Controlla se i campi sono stati davvero rimossi
                        remaining_unwanted = [f for f in final_fields if f.lower() in ['layer', 'path']]
                        if remaining_unwanted:
                            QgsMessageLog.logMessage(f"⚠️ WARNING: Questi campi sono ancora presenti: {remaining_unwanted}", "QUtility", Qgis.Warning)
                        else:
                            QgsMessageLog.logMessage(f"✅ Successfully removed {len(field_names_to_remove)} fields manually: {field_names_to_remove}", "QUtility", Qgis.Info)
                            
                    except Exception as e:
                        QgsMessageLog.logMessage(f"⚠️ Error during manual field removal: {str(e)}", "QUtility", Qgis.Critical)
                        QgsMessageLog.logMessage("⚠️ Warning: Using original layer with all fields", "QUtility", Qgis.Warning)
                else:
                    QgsMessageLog.logMessage("🔧 No 'layer' or 'path' fields found to remove", "QUtility", Qgis.Info)
            else:
                if add_fields:
                    QgsMessageLog.logMessage("📋 Keeping 'layer' and 'path' fields as requested", "QUtility", Qgis.Info)
            
            # Nome per il layer di output
            merged_name = "Merged"
            
            # **ASSEGNA NOME E AGGIUNGE AL PROGETTO**
            merged_layer.setName(merged_name)
            QgsProject.instance().addMapLayer(merged_layer)
            
            # **MESSAGGIO DI SUCCESSO**
            end_time = time.time()
            seconds = end_time - start_time
            
            # Crea la lista dei nomi dei layer (mantieni questa riga)
            layer_names = [layer.name() for layer in selected_layers]

            # Versione ultra-semplice e sempre allineata
            success_message = (
                f"Batch Merger completed successfully!\n\n"
                f"Merged layers: {len(selected_layers)}\n"
                f"Total features: {merged_layer.featureCount()}\n" 
                f"CRS: {target_crs.authid()}\n"
                f"Processing time: {seconds:.2f} seconds\n\n"
                f"Layers:\n{chr(10).join([f'• {name}' for name in layer_names])}"
            )

            QMessageBox.information(self.dlg, "Success", success_message)
            QgsMessageLog.logMessage(f"✅ Batch Merger completed in {seconds:.2f} seconds", "QUtility", Qgis.Info)
                
        except Exception as e:
            QMessageBox.critical(self.dlg, "Error", f"An error occurred: {str(e)}")
            QgsMessageLog.logMessage(f"Batch Merger error: {str(e)}", "QUtility", Qgis.Critical)