# SPDX-License-Identifier: GPL-2.0-or-later

# QGIS
from qgis.core import QgsGeometry, QgsWkbTypes
from qgis.utils import qgsfunction

# Projet
from qsfcgal.core.sfcgal_wrapper import QgsGeometry_to_SFCGAL, SFCGAL_to_QgsGeometry


@qgsfunction(args="auto", group="SFCGAL", register=False)
def cg_line_sub_string(value, start: float, end: float, feature, parent):
    """
    <style>
    span { color: red }

    </style>
    <h1>Description</h1>

    Computes the line which is the section of the input line starting and ending at the given fractional locations.
    The first argument must be a LINESTRING. The second and third arguments are values in the range [0, 1] representing the
    start and end locations as fractions of line length. The Z and M values are interpolated for added endpoints if present.
    The input layer can only be a line.
    <br/><br/>
    <h1>Auguments</h1>
    <table>
        <tr><td><span>input</span></td><td>geometry</td></tr>
        <tr><td><span>start</span></td><td>float</td></tr>
        <tr><td><span>end</span></td><td>float</td></tr>
    </table>
    <br/><br/>
    <h1>Syntax</h1>
    cg_line_sub_string(<span>@geometry</span>,<span>start</span>,<span>end</span>)
    <br/><br/>
    <h1>Examples</h1>
    <ul>
        <li> cg_line_sub_string('LINESTRING (30 10, 10 30, 40 40)', 0.1, 0.9)) -> 'LineString (25.763932 14.236068, 10 30, 34.316718 38.105573)'</li>
    </ul>
    """  # noqa: E501,W505
    if (start > 1 or start < 0) or (end > 1 or end < 0) or start > end:
        return None

    if (
        not QgsWkbTypes.geometryType(value.wkbType())
        == QgsWkbTypes.GeometryType.LineGeometry
    ):
        return None

    if value.isMultipart():
        result_lines = []
        line = value.asGeometryCollection()
        line_strings = [
            geom
            for geom in line
            if value.type() == QgsWkbTypes.GeometryType.LineGeometry
        ]
        for i, line in enumerate(line_strings):
            geom_sfcgal = QgsGeometry_to_SFCGAL(line)
            result_geom = geom_sfcgal.line_sub_string(start, end)
            line_result = SFCGAL_to_QgsGeometry(result_geom)
            result_lines.append(line_result)
            new_geom = QgsGeometry()
            for line_string in result_lines:
                if new_geom.isEmpty():
                    new_geom = line_string
                else:
                    new_geom = new_geom.combine(line_string)

        return new_geom

    else:
        geom_input = QgsGeometry_to_SFCGAL(value)
        result_geom = geom_input.line_sub_string(start, end)
        new_geom = SFCGAL_to_QgsGeometry(result_geom)
        return new_geom
