from pathlib import Path

from qgis.core import (
    QgsProcessingAlgorithm,
    QgsProcessingException,
    QgsProcessingFeedback,
    QgsProcessingParameterFile,
    QgsProcessingParameterFileDestination,
)
from qgis.PyQt.QtCore import QCoreApplication

from CityForge.merged_cityjson import merged_cityjson


class MergedCityJSON(QgsProcessingAlgorithm):
    """
    QGIS algorithm to merge all JSON files from a folder
    into a single output JSON file.

    Parameters:
        FOLDER (QgsProcessingParameterFile): Folder containing JSON files to merge.
        OUTPUT (QgsProcessingParameterFileDestination): Path to the merged output JSON file.
    """

    def tr(self, message: str):
        """
        Returns a translatable string with the self.tr() function.
        """
        return QCoreApplication.translate(self.__class__.__name__, message)

    def createInstance(self):
        return MergedCityJSON()

    def name(self):
        """
        Returns the algorithm name, used for identifying the algorithm. This
        string should be fixed for the algorithm, and must not be localised.
        The name should be unique within each provider. Names should contain
        lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        """
        return "-cityjson-merged"

    def displayName(self):
        """
        Returns the translated algorithm name, which should be used for any
        user-visible display of the algorithm name.
        """
        return self.tr("Merged CityJSON")

    def group(self):
        """
        Returns the name of the group this algorithm belongs to. This string
        should be localised.
        """
        return self.tr("CityForge")

    def shortHelpString(self):
        """
        Returns a localised short helper string for the algorithm. This string
        should provide a basic description about what the algorithm does and the
        parameters and outputs associated with it.
        """

        return self.tr(
            """Merged CityJSON files.
            - Takes a folder containing all the CityJSON files to be merged.
                It is possible to include other files in the folder, but all the CityJSON files will be merged.
            - Takes an output file.
            """
        )

    def initAlgorithm(self, config=None):  # pylint: disable=unused-argument
        """
        Defines the inputs and outputs of the algorithm.
        """

        self.FOLDER = "folder"
        self.OUTPUT = "output"

        self.addParameter(
            QgsProcessingParameterFile(
                self.FOLDER,
                self.tr("Input folder"),
                behavior=QgsProcessingParameterFile.Folder,
            )
        )

        self.addParameter(QgsProcessingParameterFileDestination(self.OUTPUT))

    def processAlgorithm(self, parameters, context, feedback: QgsProcessingFeedback):
        """
        Executes the merged_cityjson function to merge all JSON files
        from the input folder into a single output file.

        Parameters:
            parameters (dict): Dictionary of algorithm parameters.
            context (QgsProcessingContext): Execution context.
            feedback (QgsProcessingFeedback): Used to send messages or progress updates.
        """

        files = self.parameterAsFile(parameters, self.FOLDER, context)
        output = self.parameterAsFile(parameters, self.OUTPUT, context)

        # Keep only the json files
        dir_files = Path(files)
        files = list(dir_files.glob("*.json"))

        # Add ".json" extension if it is not already present
        if not str(output).endswith(".json"):
            output = str(output) + ".json"
        try:
            feedback.pushInfo(
                self.tr("Running merged cityjson, this can take a while...")
            )
            merged_cityjson(files, output)
            feedback.pushInfo(self.tr("CityJSON merge completed successfully."))
        except Exception as e:
            raise QgsProcessingException(e)
        return {}
