# SPDX-FileCopyrightText: 2025 XLeitstelle Planen und Bauen <xleitstelle@gv.hamburg.de>
# SPDX-FileContributor: Tobias Kraft <tobias.kraft@gv.hamburg.de>
#
# SPDX-License-Identifier: EUPL-1.2

from qgis.core import (
    Qgis,
    QgsApplication,
    QgsFeature,
    QgsGeometry,
    QgsMapLayer,
)
from qgis.gui import (
    QgsMapLayerAction,
    QgsMapLayerActionContext,
)
from qgis.PyQt.QtCore import QObject, pyqtSlot
from qgis.utils import iface

from xmas_plugin.util.metadata import PLUGIN_DIR_NAME, PLUGIN_NAME


class ReverseLine(QgsMapLayerAction):
    def __init__(self, parent: QObject | None = None):
        super().__init__(
            "Laufrichtung umdrehen",
            parent,
            Qgis.MapLayerActionTargets(
                Qgis.MapLayerActionTarget.SingleFeature
                | Qgis.MapLayerActionTarget.MultipleFeatures
            ),
            QgsApplication.instance().getThemeIcon("mActionReverseLine.svg"),
            Qgis.MapLayerActionFlags(),
        )
        self.triggeredForFeatureV2.connect(self._trigger_for_feature)
        self.triggeredForFeaturesV2.connect(self._trigger_for_features)

    def canRunUsingLayer(
        self,
        layer: QgsMapLayer | None,
        _: QgsMapLayerActionContext = QgsMapLayerActionContext(),
    ) -> bool:
        return (
            layer.customProperty(f"{PLUGIN_DIR_NAME}/layer_type") is not None
            and layer.geometryType().name == "Line"
            and layer.isEditable()
            if layer
            else False
        )

    @pyqtSlot("QgsMapLayer*", QgsFeature, QgsMapLayerActionContext)
    def _trigger_for_feature(
        self,
        layer: QgsMapLayer,
        feature: QgsFeature,
        _: QgsMapLayerActionContext,
    ) -> None:
        self._reverse_line(layer, [feature])

    @pyqtSlot("QgsMapLayer*", "QList<QgsFeature>", QgsMapLayerActionContext)
    def _trigger_for_features(
        self,
        layer: QgsMapLayer,
        features: list[QgsFeature],
        _: QgsMapLayerActionContext,
    ) -> None:
        self._reverse_line(layer, features)

    def _reverse_line(
        self,
        layer: QgsMapLayer,
        features: list[QgsFeature],
    ) -> None:
        try:
            reversed = 0
            for feature in features:
                reversed_geometry = feature.geometry().constGet().reversed()
                layer.beginEditCommand("reverse geometry")
                try:
                    layer.changeGeometry(feature.id(), QgsGeometry(reversed_geometry))
                finally:
                    layer.endEditCommand()
                reversed += 1
            iface.messageBar().pushSuccess(
                PLUGIN_NAME,
                f"Laufrichtung für {reversed} Feature(s) umgedreht.",
            )
        except Exception as e:
            iface.messageBar().pushError(
                PLUGIN_NAME, f"Fehler beim Umdrehen der Laufrichtung: {e!r}"
            )
