# Copyright (c) 2026, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
# Copyright (c) 2026, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
import shapely.wkb
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtGui import QCursor
from qgis.core import QgsSpatialIndex, QgsGeometry, QgsFeature, edit
from qgis.gui import QgsMapToolPan
from shapely.ops import substring
from .net_editor import NetEditor


class LinkBreaker(NetEditor):
    def __init__(self, qgis_proj):
        super().__init__(qgis_proj)
        self.link_layer = self._PQgis.layers["link"][0]

    def do_break_link(self):
        self.canvas.setCursor(QCursor(Qt.CrossCursor))
        self.canvas.setMapTool(self.clickTool)
        self.clickTool.clicked.connect(self.execute_break_link)

    def execute_break_link(self):
        if not self.link_layer.isEditable():
            return
        node_layer = self._PQgis.layers["node"][0]

        self.canvas.setCursor(QCursor(Qt.ArrowCursor))
        self.canvas.setMapTool(None)
        self.point_found_break()
        self.editing()

        for layer in [self.link_layer, node_layer]:
            layer.reload()
            layer.triggerRepaint()

        self.canvas.setMapTool(QgsMapToolPan(self.canvas))
        self.canvas.setExtent(self.canvas.extent())
        self.canvas.refresh()

    def point_found_break(self):
        point = self.clickTool.toLayerCoordinates(self.link_layer, self.clickTool.point)

        lindex = QgsSpatialIndex(self.link_layer.getFeatures())
        nearest = lindex.nearestNeighbor(point, 1)
        pnt = QgsGeometry().fromPointXY(point)
        distances = [self.link_layer.getFeature(i).geometry().distance(pnt) for i in nearest]
        fid = nearest[distances.index(min(distances))]
        feat = self.link_layer.getFeature(fid)

        layer_fields = self.link_layer.fields()

        g = QgsGeometry()
        g = g.fromPointXY(point)
        pnt = shapely.wkb.loads(g.asWkb().data())

        # first part
        wkb = feat.geometry().asWkb().data()
        shpgeo = shapely.wkb.loads(wkb)
        intersec = shpgeo.project(pnt)
        geo1 = substring(shpgeo, 0, intersec)
        g1 = QgsGeometry()
        g1.fromWkb(geo1.wkb)

        nfeat = QgsFeature(layer_fields)
        for f in layer_fields:
            if f.name() == "link":
                pass
            elif f.name() in ["bearing_a", "bearing_b", "length", "node_a", "node_b", "setback_a", "setback_b"]:
                nfeat.setAttribute(f.name(), 0)
            else:
                nfeat.setAttribute(f.name(), feat[f.name()])
        nfeat.setGeometry(g1)

        #  second part
        geo2 = substring(shpgeo, intersec, feat["length"])
        if min(geo1.length, geo2.length) > 0:
            g2 = QgsGeometry()
            g2.fromWkb(geo2.wkb)

            self.link_layer.startEditing()
            self.link_layer.changeGeometry(fid, g2)
            self.link_layer.addFeatures([nfeat])
            self.link_layer.commitChanges()
