import os
from qgis.PyQt import QtGui, QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal, QSettings, Qt, QThread, pyqtSlot
from qgis.PyQt.QtWidgets import QFileDialog, QListWidgetItem, QMessageBox, QProgressBar
from qgis.core import (QgsProject, QgsVectorLayer, QgsRasterLayer, 
                       QgsCoordinateReferenceSystem, Qgis, QgsWkbTypes,
                       QgsCoordinateTransform, QgsGeometry, QgsRectangle,
                       QgsApplication, QgsSettings)
from qgis.utils import iface
import processing
from .utils.crs_analyzer import CRSAnalyzer

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'crs_finder_dockwidget_base.ui'))

class CRSAnalysisWorker(QThread):
    """Worker thread for CRS analysis to prevent UI freezing"""
    analysis_finished = pyqtSignal(list)
    analysis_error = pyqtSignal(str)
    
    def __init__(self, analyzer, extent, is_vector):
        super().__init__()
        self.analyzer = analyzer
        self.extent = extent
        self.is_vector = is_vector
    
    def run(self):
        try:
            suggested_crs = self.analyzer.get_suitable_crs(self.extent, self.is_vector, max_results=20)
            self.analysis_finished.emit(suggested_crs)
        except Exception as e:
            self.analysis_error.emit(str(e))

class CRSFinderDockWidget(QtWidgets.QDockWidget, FORM_CLASS):
    closingPlugin = pyqtSignal()

    def __init__(self, iface, parent=None):
        super(CRSFinderDockWidget, self).__init__(parent)
        self.setupUi(self)
        self.iface = iface
        self.current_layer = None
        self.temp_layer = None
        self.current_file_path = None  # Track current file path
        self.crs_analyzer = CRSAnalyzer()
        self.worker_thread = None
        
        # Add progress bar
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.inputLayout.addWidget(self.progress_bar)
        
        # Connect signals
        self.browseButton.clicked.connect(self.browse_file)
        self.layerComboBox.currentTextChanged.connect(self.layer_changed)
        self.analyzeButton.clicked.connect(self.analyze_layer)
        self.crsListWidget.itemClicked.connect(self.assign_crs_to_layer)
        self.refreshButton.clicked.connect(self.refresh_layers)
        self.detectButton.clicked.connect(self.detect_crs_from_coordinates)
        
        # Populate initial layer list
        self.refresh_layers()

    def closeEvent(self, event):
        if self.worker_thread and self.worker_thread.isRunning():
            self.worker_thread.quit()
            self.worker_thread.wait()
        self.closingPlugin.emit()
        event.accept()

    def get_prj_crs_from_shapefile(self, shapefile_path):
        """Extract CRS from .prj file associated with a shapefile"""
        try:
            # Get the .prj file path
            prj_path = os.path.splitext(shapefile_path)[0] + '.prj'
            
            if not os.path.exists(prj_path):
                return None
            
            # Read the WKT from .prj file
            with open(prj_path, 'r', encoding='utf-8') as prj_file:
                wkt = prj_file.read().strip()
            
            if not wkt:
                return None
            
            # Create CRS from WKT
            crs = QgsCoordinateReferenceSystem()
            if crs.createFromWkt(wkt):
                return {
                    'crs': crs,
                    'wkt': wkt,
                    'source': '.prj file'
                }
            else:
                # Try alternative methods if WKT fails
                if crs.createFromProj(wkt):
                    return {
                        'crs': crs,
                        'wkt': wkt,
                        'source': '.prj file (PROJ)'
                    }
                
        except Exception as e:
            self.show_message(f"Error reading .prj file: {str(e)}", Qgis.Warning)
        
        return None

    def get_layer_source_path(self, layer):
        """Get the source file path for a layer"""
        try:
            if isinstance(layer, QgsVectorLayer):
                source = layer.source()
                # Handle different source formats
                if '|' in source:
                    # Remove layer subset specifications
                    source = source.split('|')[0]
                return source
            elif isinstance(layer, QgsRasterLayer):
                return layer.source()
        except:
            pass
        return None

    def browse_file(self):
        """Open file dialog to select vector or raster file"""
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.ExistingFile)
        file_dialog.setNameFilter(
            "GIS Files (*.shp *.gpkg *.geojson *.kml *.tif *.tiff *.img *.asc);;All Files (*)")
        
        if file_dialog.exec_():
            file_path = file_dialog.selectedFiles()[0]
            self.filePathLineEdit.setText(file_path)
            self.current_file_path = file_path
            self.load_selected_file(file_path)

    def load_selected_file(self, file_path):
        """Load the selected file as a layer"""
        file_extension = os.path.splitext(file_path)[1].lower()
        layer_name = os.path.basename(file_path)
        
        try:
            if file_extension in ['.shp', '.gpkg', '.geojson', '.kml']:
                layer = QgsVectorLayer(file_path, layer_name, "ogr")
            elif file_extension in ['.tif', '.tiff', '.img', '.asc']:
                layer = QgsRasterLayer(file_path, layer_name, "gdal")
            else:
                self.show_message("Unsupported file format", Qgis.Warning)
                return
            
            if not layer.isValid():
                self.show_message("Invalid layer loaded", Qgis.Critical)
                return
            
            QgsProject.instance().addMapLayer(layer)
            self.refresh_layers()
            
            # Set the newly loaded layer as current
            layer_index = self.layerComboBox.findText(layer_name)
            if layer_index >= 0:
                self.layerComboBox.setCurrentIndex(layer_index)
            
            self.show_message(f"Layer '{layer_name}' loaded successfully", Qgis.Success)
            
            # Auto-analyze if it's a shapefile
            if file_extension == '.shp':
                self.auto_analyze_shapefile()
            
        except Exception as e:
            self.show_message(f"Error loading file: {str(e)}", Qgis.Critical)

    def auto_analyze_shapefile(self):
        """Automatically analyze shapefile and show .prj file CRS if available"""
        if not self.current_file_path or not self.current_layer:
            return
        
        if self.current_file_path.lower().endswith('.shp'):
            # Check for .prj file CRS
            prj_crs_info = self.get_prj_crs_from_shapefile(self.current_file_path)
            
            if prj_crs_info:
                crs = prj_crs_info['crs']
                if crs.isValid():
                    # Create a special CRS entry for .prj file
                    prj_crs_entry = {
                        'authid': crs.authid() if crs.authid() else 'Custom',
                        'description': f"{crs.description()} (from .prj file)",
                        'type': 'geographic' if crs.isGeographic() else 'projected',
                        'score': 150,  # Highest priority
                        'crs_object': crs,
                        'source': '.prj file',
                        'is_prj_file': True
                    }
                    
                    # Get other suggestions
                    extent = self.get_layer_extent_for_analysis()
                    if extent:
                        coord_info = self.crs_analyzer.detect_coordinate_type(extent)
                        other_crs = self.crs_analyzer.get_suitable_crs(extent, True, max_results=10)
                        
                        # Add coordinate detection to all entries
                        for crs_entry in other_crs:
                            crs_entry['coord_detection'] = coord_info
                        prj_crs_entry['coord_detection'] = coord_info
                        
                        # Combine with .prj file CRS at the top
                        all_crs = [prj_crs_entry] + other_crs
                    else:
                        all_crs = [prj_crs_entry]
                    
                    self.populate_crs_list(all_crs)
                    
                    self.show_message(f"Found CRS in .prj file: {crs.authid() or 'Custom'} - {crs.description()}", Qgis.Success)
                else:
                    self.show_message("Found .prj file but CRS is invalid", Qgis.Warning)

    def refresh_layers(self):
        """Refresh the layer combo box with current project layers"""
        self.layerComboBox.clear()
        self.layerComboBox.addItem("Select a layer...")
        
        for layer in QgsProject.instance().mapLayers().values():
            if isinstance(layer, (QgsVectorLayer, QgsRasterLayer)):
                self.layerComboBox.addItem(layer.name(), layer.id())

    def layer_changed(self):
        """Handle layer selection change - enhanced to show CRS status and check for .prj file"""
        if self.layerComboBox.currentIndex() > 0:
            layer_id = self.layerComboBox.currentData()
            self.current_layer = QgsProject.instance().mapLayer(layer_id)
            
            if self.current_layer:
                # Get layer source path
                self.current_file_path = self.get_layer_source_path(self.current_layer)
                
                # Display current CRS status
                crs = self.current_layer.crs()
                layer_type = "Raster" if isinstance(self.current_layer, QgsRasterLayer) else "Vector"
                
                if crs.isValid():
                    crs_status = f"Current CRS ({layer_type}): {crs.authid()} - {crs.description()}"
                    self.currentCrsLabel.setStyleSheet("color: black;")
                else:
                    crs_status = f"Current CRS ({layer_type}): ⚠️ Unknown/Not defined"
                    self.currentCrsLabel.setStyleSheet("color: red; font-weight: bold;")
                
                self.currentCrsLabel.setText(crs_status)
                
                # Clear previous CRS list
                self.crsListWidget.clear()
                
                # Enable buttons
                self.analyzeButton.setEnabled(True)
                self.detectButton.setEnabled(True)
                
                # Check for .prj file if it's a shapefile
                if (self.current_file_path and 
                    self.current_file_path.lower().endswith('.shp')):
                    self.check_prj_file_status()
                
                # Show layer extent info for debugging
                extent = self.current_layer.extent()
                extent_info = f"Layer extent: {extent.xMinimum():.2f}, {extent.yMinimum():.2f} : {extent.xMaximum():.2f}, {extent.yMaximum():.2f}"
                self.show_message(extent_info, Qgis.Info)
        else:
            self.current_layer = None
            self.current_file_path = None
            self.currentCrsLabel.setText("Current CRS: None")
            self.currentCrsLabel.setStyleSheet("color: black;")
            self.crsListWidget.clear()
            self.analyzeButton.setEnabled(False)
            self.detectButton.setEnabled(False)

    def check_prj_file_status(self):
        """Check and display .prj file status for shapefiles"""
        if not self.current_file_path or not self.current_file_path.lower().endswith('.shp'):
            return
        
        prj_path = os.path.splitext(self.current_file_path)[0] + '.prj'
        
        if os.path.exists(prj_path):
            prj_crs_info = self.get_prj_crs_from_shapefile(self.current_file_path)
            if prj_crs_info:
                crs = prj_crs_info['crs']
                if crs.isValid():
                    self.show_message(f"📄 .prj file found with CRS: {crs.authid() or 'Custom'}", Qgis.Info)
                else:
                    self.show_message("📄 .prj file found but contains invalid CRS", Qgis.Warning)
            else:
                self.show_message("📄 .prj file found but could not be read", Qgis.Warning)
        else:
            self.show_message("⚠️ No .prj file found for this shapefile", Qgis.Warning)

    def detect_crs_from_coordinates(self):
        """Detect CRS based on coordinate ranges, including .prj file check"""
        if not self.current_layer:
            self.show_message("Please select a layer first", Qgis.Warning)
            return
        
        try:
            layer_extent = self.current_layer.extent()
            all_suggestions = []
            
            # First, check for .prj file if it's a shapefile
            if (self.current_file_path and 
                self.current_file_path.lower().endswith('.shp')):
                
                prj_crs_info = self.get_prj_crs_from_shapefile(self.current_file_path)
                if prj_crs_info:
                    crs = prj_crs_info['crs']
                    if crs.isValid():
                        prj_suggestion = {
                            'authid': crs.authid() if crs.authid() else 'Custom',
                            'description': f"{crs.description()} (from .prj file)",
                            'type': 'geographic' if crs.isGeographic() else 'projected',
                            'score': 150,  # Highest priority
                            'crs_object': crs,
                            'source': '.prj file',
                            'is_prj_file': True
                        }
                        all_suggestions.append(prj_suggestion)
            
            # Detect coordinate type
            coord_info = self.crs_analyzer.detect_coordinate_type(layer_extent)
            
            # Show coordinate detection results
            coord_msg = f"🔍 Detected: {coord_info['type']} coordinates ({coord_info.get('units', 'unknown')} units) - Confidence: {coord_info['confidence']}%"
            self.show_message(coord_msg, Qgis.Info)
            
            # Get likely CRS based on detection
            likely_crs = self.crs_analyzer.detect_likely_crs_from_extent(layer_extent)
            
            # Add coordinate detection info to all CRS entries
            for crs in likely_crs:
                crs['coord_detection'] = coord_info
            for crs in all_suggestions:
                crs['coord_detection'] = coord_info
            
            # Combine suggestions
            all_suggestions.extend(likely_crs)
            
            if all_suggestions:
                self.populate_crs_list(all_suggestions)
                msg_count = len(all_suggestions)
                if any(crs.get('is_prj_file') for crs in all_suggestions):
                    self.show_message(f"Found .prj file CRS + {msg_count-1} coordinate-based suggestions", Qgis.Success)
                else:
                    self.show_message(f"Found {msg_count} likely CRS based on coordinates", Qgis.Success)
            else:
                self.show_message("Could not detect likely CRS from coordinates", Qgis.Warning)
                # Show common CRS as fallback
                common_crs = self.crs_analyzer.get_common_crs()
                for crs in common_crs:
                    crs['coord_detection'] = coord_info
                if all_suggestions:  # Include .prj file if found
                    common_crs = all_suggestions + common_crs
                self.populate_crs_list(common_crs)
                
        except Exception as e:
            self.show_message(f"Error detecting CRS: {str(e)}", Qgis.Critical)

    def analyze_layer(self):
        """Enhanced analysis with .prj file priority and coordinate type detection"""
        if not self.current_layer:
            self.show_message("Please select a layer first", Qgis.Warning)
            return

        self.analyzeButton.setText("Analyzing...")
        self.analyzeButton.setEnabled(False)
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)
        
        try:
            # Check for .prj file first (for shapefiles)
            prj_suggestions = []
            if (self.current_file_path and 
                self.current_file_path.lower().endswith('.shp')):
                
                prj_crs_info = self.get_prj_crs_from_shapefile(self.current_file_path)
                if prj_crs_info:
                    crs = prj_crs_info['crs']
                    if crs.isValid():
                        prj_suggestion = {
                            'authid': crs.authid() if crs.authid() else 'Custom',
                            'description': f"{crs.description()} (from .prj file)",
                            'type': 'geographic' if crs.isGeographic() else 'projected',
                            'score': 150,  # Highest priority
                            'crs_object': crs,
                            'source': '.prj file',
                            'is_prj_file': True
                        }
                        prj_suggestions.append(prj_suggestion)
            
            # Get layer extent and detect coordinate type
            extent = self.get_layer_extent_for_analysis()
            
            if extent:
                # Show coordinate detection results
                coord_info = self.crs_analyzer.detect_coordinate_type(extent)
                coord_msg = f"🔍 Detected {coord_info['type']} coordinates ({coord_info.get('units', 'unknown')} units) - {coord_info['confidence']}% confidence"
                self.show_message(coord_msg, Qgis.Info)
                
                # Add coordinate info to .prj suggestions
                for crs in prj_suggestions:
                    crs['coord_detection'] = coord_info
            
            is_vector = isinstance(self.current_layer, QgsVectorLayer)
            
            # Store .prj suggestions for later combination
            self.prj_suggestions = prj_suggestions
            
            # Create worker thread for analysis
            self.worker_thread = CRSAnalysisWorker(self.crs_analyzer, extent, is_vector)
            self.worker_thread.analysis_finished.connect(self.on_analysis_finished)
            self.worker_thread.analysis_error.connect(self.on_analysis_error)
            self.worker_thread.start()
            
        except Exception as e:
            self.on_analysis_error(str(e))

    @pyqtSlot(list)
    def on_analysis_finished(self, suggested_crs):
        """Handle analysis completion with .prj file priority"""
        self.progress_bar.setVisible(False)
        self.analyzeButton.setText("Find from QGIS CRS DB")
        self.analyzeButton.setEnabled(True)
        
        # Combine .prj file suggestions with analyzed suggestions
        all_suggestions = getattr(self, 'prj_suggestions', []) + suggested_crs
        
        if all_suggestions:
            self.populate_crs_list(all_suggestions)
            
            prj_count = len(getattr(self, 'prj_suggestions', []))
            db_count = len(suggested_crs)
            
            if prj_count > 0:
                self.show_message(f"Found {prj_count} .prj file CRS + {db_count} database suggestions", Qgis.Success)
            else:
                self.show_message(f"Found {db_count} suitable CRS options from QGIS database", Qgis.Success)
        else:
            # Fallback to common CRS
            common_crs = self.crs_analyzer.get_common_crs()
            self.populate_crs_list(common_crs)
            self.show_message("No specific CRS found - showing common options", Qgis.Warning)

    @pyqtSlot(str)
    def on_analysis_error(self, error_message):
        """Handle analysis error"""
        self.progress_bar.setVisible(False)
        self.analyzeButton.setText("Find from QGIS DB")
        self.analyzeButton.setEnabled(True)
        
        self.show_message(f"Error analyzing layer: {error_message}", Qgis.Critical)
        
        # Still show .prj file suggestions if available
        prj_suggestions = getattr(self, 'prj_suggestions', [])
        if prj_suggestions:
            self.populate_crs_list(prj_suggestions)
            self.show_message("Analysis failed, but showing .prj file CRS", Qgis.Warning)
        else:
            # Show common CRS as fallback
            common_crs = self.crs_analyzer.get_common_crs()
            self.populate_crs_list(common_crs)

    def get_layer_extent_for_analysis(self):
        """Get layer extent for analysis - handle layers without proper CRS"""
        if not self.current_layer:
            return None
        
        layer_extent = self.current_layer.extent()
        layer_crs = self.current_layer.crs()
        
        # If layer has no CRS or invalid CRS, return raw extent for coordinate type detection
        if not layer_crs.isValid():
            return layer_extent
        
        # If layer has valid CRS and it's already WGS84
        if layer_crs.authid() == 'EPSG:4326':
            return layer_extent
        
        # For layers with valid CRS but coordinates might be in meters, 
        # return raw extent for coordinate type detection
        return layer_extent

    def populate_crs_list(self, crs_list):
        """Populate the CRS list widget with enhanced .prj file priority display"""
        self.crsListWidget.clear()
        
        # Add coordinate detection info at the top if available
        if crs_list and len(crs_list) > 0 and 'coord_detection' in crs_list[0]:
            coord_info = crs_list[0]['coord_detection']
            
            # Create info item
            info_item = QListWidgetItem()
            info_text = f"🔍 Detected: {coord_info['type'].title()} coordinates "
            info_text += f"({coord_info.get('units', 'unknown')} units) "
            info_text += f"- Confidence: {coord_info['confidence']}%"
            
            info_item.setText(info_text)
            info_item.setBackground(QtGui.QColor(230, 240, 255))  # Light blue background
            info_item.setFlags(info_item.flags() & ~Qt.ItemIsSelectable)  # Make non-selectable
            
            # Enhanced tooltip
            tooltip = f"Coordinate Detection Results:\n"
            tooltip += f"Type: {coord_info['type'].title()}\n"
            tooltip += f"Units: {coord_info.get('units', 'unknown')}\n"
            tooltip += f"Confidence: {coord_info['confidence']}%\n"
            tooltip += f"Reason: {coord_info['reason']}\n"
            tooltip += f"Center: {coord_info['center']}\n"
            tooltip += f"Range: {coord_info['range']}"
            
            info_item.setToolTip(tooltip)
            self.crsListWidget.addItem(info_item)
            
            # Add separator
            separator = QListWidgetItem()
            separator.setText("─" * 50)
            separator.setFlags(separator.flags() & ~Qt.ItemIsSelectable)
            self.crsListWidget.addItem(separator)
        
        # Add CRS options with .prj file priority
        for crs_info in crs_list:
            # Skip if this is just coordinate detection info
            if not isinstance(crs_info, dict) or 'authid' not in crs_info:
                continue
                
            item = QListWidgetItem()
            
            # Enhanced display with .prj file priority and coordinate type compatibility
            score = crs_info.get('score', 0)
            crs_type = crs_info.get('type', 'unknown')
            is_prj_file = crs_info.get('is_prj_file', False)
            
            display_text = f"{crs_info['authid']} - {crs_info['description']}"
            
            # Add special indicator for .prj file
            if is_prj_file:
                type_indicator = "📄"  # File icon for .prj file
                display_text = f"{type_indicator} {display_text}"
            else:
                # Regular type indicator
                type_indicator = "🌍" if crs_type == 'geographic' else "📐"
                display_text = f"{type_indicator} {display_text}"
            
            if score > 0:
                display_text += f" (Score: {score})"
            
            item.setText(display_text)
            item.setData(Qt.UserRole, crs_info)
            
            # Enhanced tooltip
            tooltip = f"EPSG: {crs_info['authid']}\n"
            tooltip += f"Description: {crs_info['description']}\n"
            tooltip += f"Type: {crs_info['type']}\n"
            tooltip += f"Source: {crs_info.get('source', 'QGIS Database')}\n"
            tooltip += f"Suitability Score: {crs_info.get('score', 'N/A')}\n"
            
            if is_prj_file:
                tooltip += f"\n⭐ This CRS is from the .prj file associated with your shapefile"
            
            if 'coord_detection' in crs_info:
                coord_info = crs_info['coord_detection']
                tooltip += f"\nCoordinate Detection:\n"
                tooltip += f"- Detected Type: {coord_info['type']}\n"
                tooltip += f"- Detected Units: {coord_info.get('units', 'unknown')}\n"
                tooltip += f"- Confidence: {coord_info['confidence']}%"
            
            item.setToolTip(tooltip)
            
            # Enhanced color coding with .prj file priority
            if is_prj_file:
                item.setBackground(QtGui.QColor(255, 215, 0))  # Gold - .prj file priority
            elif score >= 90:
                item.setBackground(QtGui.QColor(144, 238, 144))  # Light green - excellent match
            elif score >= 70:
                item.setBackground(QtGui.QColor(255, 255, 144))  # Light yellow - good match
            elif score >= 50:
                item.setBackground(QtGui.QColor(255, 218, 185))  # Light orange - fair match
            else:
                item.setBackground(QtGui.QColor(255, 182, 193))  # Light red - poor match
            
            self.crsListWidget.addItem(item)

    def assign_crs_to_layer(self, item):
        """Assign the selected CRS to the current layer using different approaches for raster and vector"""
        if not self.current_layer:
            self.show_message("No layer selected", Qgis.Warning)
            return
        
        # Check if item is selectable (not info or separator)
        if not (item.flags() & Qt.ItemIsSelectable):
            return
        
        crs_info = item.data(Qt.UserRole)
        if not crs_info:
            return
            
        target_crs = crs_info.get('crs_object') or QgsCoordinateReferenceSystem(crs_info['authid'])
        
        if not target_crs.isValid():
            self.show_message("Invalid CRS selected", Qgis.Critical)
            return
        
        # Check if the target CRS is the same as current CRS
        current_crs = self.current_layer.crs()
        if current_crs.isValid() and current_crs.authid() == target_crs.authid():
            self.show_message(f"Layer already has CRS {target_crs.authid()} assigned", Qgis.Info)
            return
        
        try:
            # Remove previous temporary layer
            self.remove_temp_layer()
            
            # Different approaches for Vector and Raster layers
            if isinstance(self.current_layer, QgsVectorLayer):
                # VECTOR LAYER APPROACH: Use cloning and setCrs
                self.show_message("Processing vector layer with clone method...", Qgis.Info)
                temp_layer = self.current_layer.clone()
                temp_layer.setCrs(target_crs)
                
            else:
                # RASTER LAYER APPROACH: Use setCrs method directly
                self.show_message("Processing raster layer with setCrs method...", Qgis.Info)
                
                # Temporarily disable CRS prompt to avoid popup dialogs
                settings = QgsSettings()
                old_default_behavior = settings.value("/Projections/defaultBehavior", "prompt")
                settings.setValue("/Projections/defaultBehavior", "useProject")
                
                try:
                    # Method 1: Direct setCrs on a copy of the raster layer
                    source_path = self.current_layer.source()
                    layer_name = f"{self.current_layer.name()}_temp"
                    
                    # Create new raster layer from source
                    temp_layer = QgsRasterLayer(source_path, layer_name, "gdal")
                    
                    if temp_layer.isValid():
                        # Set the CRS directly
                        temp_layer.setCrs(target_crs)
                        self.show_message("Raster CRS assigned using setCrs method", Qgis.Info)
                    else:
                        # Fallback: Use GDAL assign projection
                        self.show_message("Fallback to GDAL assign projection...", Qgis.Info)
                        result = processing.run("gdal:assignprojection", {
                            'INPUT': self.current_layer,
                            'CRS': target_crs,
                            'OUTPUT': 'TEMPORARY_OUTPUT'
                        })
                        
                        output = result['OUTPUT']
                        
                        if isinstance(output, str):
                            # Create layer from file path
                            temp_layer = QgsRasterLayer(output, layer_name, "gdal")
                            if not temp_layer.isValid():
                                raise Exception("Failed to create raster layer from GDAL output")
                        else:
                            temp_layer = output
                
                finally:
                    # Restore original CRS behavior setting
                    settings.setValue("/Projections/defaultBehavior", old_default_behavior)
            
            # Set layer name to indicate CRS assignment
            original_crs = self.current_layer.crs().authid() if self.current_layer.crs().isValid() else "Unknown"
            layer_type = "Raster" if isinstance(self.current_layer, QgsRasterLayer) else "Vector"
            
            # Special naming for .prj file CRS
            if crs_info.get('is_prj_file'):
                temp_layer.setName(f"{self.current_layer.name()} ({layer_type} - CRS from .prj: {crs_info['authid']})")
            else:
                temp_layer.setName(f"{self.current_layer.name()} ({layer_type} - CRS: {original_crs} → {crs_info['authid']})")
            
            # Add the layer with assigned CRS to the project
            self.temp_layer = temp_layer
            QgsProject.instance().addMapLayer(self.temp_layer)
            
            # Automatically zoom to the layer with proper CRS transformation
            self.zoom_to_layer_with_crs_handling(self.temp_layer)
            
            # Special message for .prj file CRS
            if crs_info.get('is_prj_file'):
                self.show_message(f"CRS from .prj file ({crs_info['authid']}) assigned to {layer_type.lower()} layer and zoomed", Qgis.Success)
            else:
                self.show_message(f"CRS {crs_info['authid']} assigned to {layer_type.lower()} layer and zoomed", Qgis.Success)
            
        except Exception as e:
            self.show_message(f"Error assigning CRS to {layer_type.lower()} layer: {str(e)}", Qgis.Critical)
            
            # Debug information
            import traceback
            print("Full traceback:")
            print(traceback.format_exc())

    def zoom_to_layer_with_crs_handling(self, layer):
        """
        Zoom to layer extent with proper CRS transformation handling
        
        Args:
            layer: QgsVectorLayer or QgsRasterLayer to zoom to
        """
        try:
            if not layer or not layer.isValid():
                self.show_message("Invalid layer for zooming", Qgis.Warning)
                return
            
            # Get the map canvas
            canvas = self.iface.mapCanvas()
            
            # Get layer extent
            layer_extent = layer.extent()
            
            if layer_extent.isEmpty():
                self.show_message("Layer has empty extent, cannot zoom", Qgis.Warning)
                return
            
            # Get the layer CRS and canvas CRS
            layer_crs = layer.crs()
            canvas_crs = canvas.mapSettings().destinationCrs()
            
            # Check if CRS transformation is needed
            if layer_crs.isValid() and canvas_crs.isValid() and layer_crs != canvas_crs:
                # Transform extent from layer CRS to canvas CRS
                try:
                    transform = QgsCoordinateTransform(layer_crs, canvas_crs, QgsProject.instance())
                    transformed_extent = transform.transformBoundingBox(layer_extent)
                    
                    # Validate transformed extent
                    if not transformed_extent.isEmpty():
                        layer_extent = transformed_extent
                    else:
                        self.show_message("Extent transformation resulted in empty bounds", Qgis.Warning)
                        # Fallback to original extent
                        pass
                        
                except Exception as transform_error:
                    self.show_message(f"CRS transformation failed: {str(transform_error)}", Qgis.Warning)
                    # Continue with original extent as fallback
                    pass
            
            # Add buffer around the extent (5% on each side)
            buffer_factor = 0.05
            width = layer_extent.width()
            height = layer_extent.height()
            
            buffered_extent = QgsRectangle(
                layer_extent.xMinimum() - (width * buffer_factor),
                layer_extent.yMinimum() - (height * buffer_factor),
                layer_extent.xMaximum() + (width * buffer_factor),
                layer_extent.yMaximum() + (height * buffer_factor)
            )
            
            # Set the canvas extent and refresh
            canvas.setExtent(buffered_extent)
            canvas.refresh()
            
            # Set as active layer
            self.iface.setActiveLayer(layer)
            
            # Optional: Flash the layer to highlight it
            self.flash_layer(layer)
            
        except Exception as e:
            self.show_message(f"Error zooming to layer: {str(e)}", Qgis.Critical)

    def flash_layer(self, layer, duration=1000):
        """
        Flash the layer to highlight it visually
        
        Args:
            layer: Layer to flash
            duration: Flash duration in milliseconds
        """
        try:
            # Simple approach: just refresh the canvas to ensure layer is visible
            canvas = self.iface.mapCanvas()
            canvas.refresh()
            
            # Show a temporary message
            layer_type = "raster" if isinstance(layer, QgsRasterLayer) else "vector"
            self.show_message(f"Zoomed to {layer_type} layer: {layer.name()}", Qgis.Info)
                
        except Exception as e:
            # If flashing fails, just continue - it's not critical
            pass

    def remove_temp_layer(self):
        """Remove the current temporary layer"""
        if self.temp_layer:
            QgsProject.instance().removeMapLayer(self.temp_layer)
            self.temp_layer = None

    def show_message(self, message, level=Qgis.Info):
        """Show message in QGIS message bar"""
        self.iface.messageBar().pushMessage("CRS Finder", message, level, duration=3)
