"""
Layer Loader for loading STAC assets as QGIS layers
"""
from qgis.core import (QgsRasterLayer, QgsProject, QgsMessageLog,
                       Qgis, QgsRasterBandStats)


class LayerLoader:
    """Load STAC assets as QGIS layers"""

    def __init__(self, iface):
        """Initialize with QGIS interface

        Args:
            iface: QGIS interface instance
        """
        self.iface = iface

    def load_cog_layer(self, item, asset_key, layer_name=None):
        """Load Cloud-Optimized GeoTIFF as QGIS layer

        Args:
            item: STACItem (PySTAC Item object)
            asset_key (str): Asset identifier (e.g., 'B04', 'red')
            layer_name (str): Optional custom layer name

        Returns:
            QgsRasterLayer: The loaded layer
        """
        try:
            # Get asset from PySTAC item
            if not hasattr(item, 'assets') or asset_key not in item.assets:
                raise ValueError(f'Asset {asset_key} not found in item')

            asset = item.assets[asset_key]

            # Get URL from asset (PySTAC way)
            url = asset.href

            if layer_name is None:
                layer_name = f"{item.id}_{asset_key}"

            # Create QGIS raster layer with vsicurl
            vsicurl_url = f"/vsicurl/{url}"
            layer = QgsRasterLayer(vsicurl_url, layer_name, 'gdal')

            if layer.isValid():
                QgsProject.instance().addMapLayer(layer)

                # Apply default styling
                self.apply_default_style(layer)

                QgsMessageLog.logMessage(
                    f'Successfully loaded {layer_name}',
                    'Open Geodata Browser',
                    Qgis.MessageLevel.Success
                )

                # Refresh canvas
                self.iface.mapCanvas().refresh()

                return layer
            else:
                error_msg = f'Failed to load layer from {url}'
                QgsMessageLog.logMessage(
                    error_msg,
                    'Open Geodata Browser',
                    Qgis.MessageLevel.Critical
                )
                raise ValueError(error_msg)

        except Exception as e:
            QgsMessageLog.logMessage(
                f'Error loading COG layer: {str(e)}',
                'Open Geodata Browser',
                Qgis.MessageLevel.Critical
            )
            raise

    def load_asset(self, asset, asset_key, item_id):
        """Load a STAC asset to QGIS

        Args:
            asset: STACAsset object
            asset_key: Asset key/name
            item_id: Item identifier
        """
        try:
            # Get href
            href = asset.href if hasattr(asset, 'href') else None

            if not href:
                raise Exception(f'No href available for asset {asset_key}')

            # Determine asset type
            asset_type = asset.type if hasattr(asset, 'type') else ''

            # Build layer name
            layer_name = f"{item_id}_{asset_key}"

            # Try to load as raster first
            if any(t in asset_type.lower()
                   for t in ['tiff', 'geotiff', 'jp2', 'jpeg', 'png', 'image']):
                layer = QgsRasterLayer(href, layer_name, 'gdal')

                if layer.isValid():
                    QgsProject.instance().addMapLayer(layer)
                    self.iface.messageBar().pushMessage(
                        'Success', f'Loaded {layer_name}', Qgis.MessageLevel.Success, 3
                    )
                    return True

            # Try to load as vector
            if any(t in asset_type.lower()
                   for t in ['json', 'geojson', 'vector']):
                layer = QgsVectorLayer(href, layer_name, 'ogr')

                if layer.isValid():
                    QgsProject.instance().addMapLayer(layer)
                    self.iface.messageBar().pushMessage(
                        'Success', f'Loaded {layer_name}', Qgis.MessageLevel.Success, 3
                    )
                    return True

            # Generic attempt
            layer = QgsRasterLayer(href, layer_name, 'gdal')
            if not layer.isValid():
                layer = QgsVectorLayer(href, layer_name, 'ogr')

            if layer.isValid():
                QgsProject.instance().addMapLayer(layer)
                return True
            else:
                raise Exception(f'Could not load asset as raster or vector')

        except Exception as e:
            raise Exception(f'Failed to load asset {asset_key}: {str(e)}')

    def load_multiple_bands(self, item, asset_keys):
        """Load multiple bands from a single item

        Args:
            item: STACItem object
            asset_keys (list): List of asset keys

        Returns:
            list: List of loaded layers
        """
        layers = []
        for asset_key in asset_keys:
            try:
                layer = self.load_cog_layer(item, asset_key)
                layers.append(layer)
            except Exception as e:
                QgsMessageLog.logMessage(
                    f'Failed to load {asset_key}: {str(e)}',
                    'Open Geodata Browser',
                    Qgis.MessageLevel.Warning
                )
        return layers

    def apply_default_style(self, layer):
        """Apply default styling to raster layer

        Args:
            layer (QgsRasterLayer): Raster layer to style
        """
        try:
            # Get statistics
            provider = layer.dataProvider()
            stats = provider.bandStatistics(1, QgsRasterBandStats.All)

            # Apply basic contrast enhancement
            from qgis.core import QgsRasterMinMaxOrigin

            renderer = layer.renderer()
            if renderer:
                renderer.setMinMaxOrigin(QgsRasterMinMaxOrigin())

            layer.triggerRepaint()

        except Exception as e:
            QgsMessageLog.logMessage(
                f'Could not apply default style: {str(e)}',
                'Open Geodata Browser',
                Qgis.MessageLevel.Warning
            )
