# -*- coding: utf-8 -*-
"""
/***************************************************************************
 SpatialAnalyzer
                                 A QGIS plugin
 This plugin provides data and tools for analyzing space
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-05-05
        git sha              : $Format:%H$
        copyright            : (C) 2018 by D.J Paek
        email                : dj.paek1@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
"""
import os

from qgis.core import (
    QgsProcessingProvider,
    QgsProcessingAlgorithm,
    QgsProcessingOutputVectorLayer,
    QgsProcessingOutputRasterLayer,
    QgsVectorLayer,
    QgsRasterLayer,
    QgsProject,
    QgsProcessingException,
)

from qgis.PyQt.QtGui import QIcon

from .algs import (
    CentralTendency,
    MeanCenterTracker,
    MedianCenterTracker,
    CentralFeatureTracker,
    StandardDistance,
    StandardDeviationEllipse,
    Gravity,
    Kmeans,
    Hierarchical,
    Dbscan,
    Hotspot,
    LocalMoransI,
    SpatialRegression,
    GeographicallyWeightedRegression,
    Pca,
    Tsne
)


pluginPath = os.path.split(os.path.dirname(__file__))[0]

class SampleFileAlgorithm(QgsProcessingAlgorithm):
    """Algorithm representing a bundled sample data file."""

    def __init__(self, file_path):
        super().__init__()
        self._path = file_path
        base_name = os.path.basename(file_path)
        # Use the filename (with extension) to ensure uniqueness of algorithm IDs
        self._alg_id = base_name.replace(".", "_")
        # Layer name should exclude the extension
        self._layer_name = os.path.splitext(base_name)[0]
        self._is_vector = file_path.lower().endswith(
            (".shp", ".gpkg", ".geojson", ".json", ".csv")
        )

    def name(self):
        return self._alg_id

    def icon(self):
        return QIcon(os.path.join(pluginPath, 'spatial_analysis', 'icons', 'sample_folder.svg'))

    def svgIconPath(self):
        return os.path.join(pluginPath, 'spatial_analysis', 'sample_folder.svg')

    def displayName(self):
        return os.path.basename(self._path)

    def group(self):
        return "Sample Data"

    def groupId(self):
        return "sample_data"

    def initAlgorithm(self, config=None):
        if self._is_vector:
            self.addOutput(QgsProcessingOutputVectorLayer("OUTPUT", "Layer"))
        else:
            self.addOutput(QgsProcessingOutputRasterLayer("OUTPUT", "Layer"))

    def processAlgorithm(self, parameters, context, feedback):
        if self._is_vector:
            layer = QgsVectorLayer(self._path, self._layer_name, "ogr")
        else:
            layer = QgsRasterLayer(self._path, self._layer_name)
        if not layer.isValid():
            raise QgsProcessingException(f"Could not load sample file: {self._path}")
        QgsProject.instance().addMapLayer(layer)
        try:
            from qgis.utils import iface

            if iface is not None:
                iface.setActiveLayer(layer)
                iface.zoomToActiveLayer()
        except Exception:
            pass
        return {"OUTPUT": layer}

    def createInstance(self):
        return SampleFileAlgorithm(self._path)


class SpatialProvider(QgsProcessingProvider):
    def __init__(self):
        super().__init__()
        self.alglist = [
            CentralTendency.CentralTendency(),
            MeanCenterTracker.MeanCenterTracker(),
            MedianCenterTracker.MedianCenterTracker(),
            CentralFeatureTracker.CentralFeatureTracker(),
            StandardDistance.StandardDistance(),
            StandardDeviationEllipse.StandardDeviationEllipse(),
            Gravity.Gravity(),
            Kmeans.Kmeans(),
            Hierarchical.Hierarchical(),
            Dbscan.Dbscan(),
            Hotspot.Hotspot(),
            LocalMoransI.LocalMoransI(),
            SpatialRegression.SpatialRegression(),
            GeographicallyWeightedRegression.GeographicallyWeightedRegression(),
            Pca.Pca(),
            Tsne.Tsne()
        ]
        
    def getAlgs(self):
        return self.alglist

    def id(self, *args, **kwargs):
        return 'spatialAnalyzer'

    def name(self, *args, **kwargs):
        return 'SpatialAnalyzer - Spatial Analysis Toolbox'

    def icon(self):
        return QIcon(os.path.join(pluginPath, 'spatial_analysis', 'icons', 'icon.svg'))

    def svgIconPath(self):
        return os.path.join(pluginPath, 'spatial_analysis', 'icon.svg')

    def loadAlgorithms(self, *args, **kwargs):
        for alg in self.alglist:
            self.addAlgorithm(alg)
        self._loadSampleDataAlgorithms()

    def _loadSampleDataAlgorithms(self):
        data_path = os.path.join(os.path.dirname(__file__), "sample_data")
        if not os.path.exists(data_path):
            return
        for filename in sorted(os.listdir(data_path)):
            path = os.path.join(data_path, filename)
            if not os.path.isfile(path):
                continue
            self.addAlgorithm(SampleFileAlgorithm(path))
