from pathlib import Path
from typing import List

from qgis.core import Qgis, QgsDataSourceUri, QgsVectorLayer

from openlog.__about__ import DIR_PLUGIN_ROOT
from openlog.datamodel.connection.interfaces.layers_interface import LayersInterface
from openlog.datamodel.connection.openlog_connection import Connection
from openlog.datamodel.connection.postgres_utils import create_datasource_uri
from openlog.toolbelt import PlgTranslator


class BDGeoLayersInterface(LayersInterface):
    def __init__(self, connection: Connection):
        """
        Implements LayersInterface for BDGeoConnection

        Args:
            connection:  Connection
        """
        super().__init__()
        self._connection = connection
        self.tr = PlgTranslator().tr

    def get_collar_layer(self) -> QgsVectorLayer:
        """
        Return collar QgsVectorLayer

        In spatialite collar geometry is available in collar geom column

        """
        if self.collar_layer is None:
            uri = create_datasource_uri(self._connection)
            uri.setDataSource("qgis", "station", "point", "", "id")
            self.collar_layer = QgsVectorLayer(uri.uri(False), "collar", "postgres")
            self.collar_layer.setReadOnly(True)
            self.collar_layer.setName(self.get_collar_layer_name())
        return self.collar_layer

    def get_collar_layer_name(self) -> str:
        """
        Get collar layer name

        Returns: (str) collar layer name

        """
        return self.tr(f"Stations - [{self._connection.database}]")

    def get_collar_layer_style_file(self) -> Path:
        """
        Get QGIS file style for collar layer

        Returns: path to QGIS style file

        """
        return DIR_PLUGIN_ROOT / "resources" / "styles" / "bdgeo" / "station_type.qml"

    def get_selected_collar_from_layer(self) -> List[str]:
        """
        Get selected collar id from QGIS layer

        Returns: [str] selected collar id

        """
        collar_layer = self.get_collar_layer()
        if collar_layer is not None:
            res = [str(f["id"]) for f in collar_layer.selectedFeatures()]
        else:
            res = []
        return res

    def select_collar_by_id(self, hole_ids: List[str]) -> None:
        """
        Select collar by ID in collar layer

        Args:
            hole_ids: List[str]: selected collar id
        """
        collar_layer = self.get_collar_layer()
        if collar_layer is not None:
            in_ = ",".join(hole_ids)
            collar_layer.selectByExpression(f'"id" IN ({in_})')

    def get_collar_trace_layer(self) -> QgsVectorLayer:
        """
        Return None for collar trace QgsVectorLayer :

        """
        return None

    def get_collar_trace_layer_name(self) -> str:
        """
        Get collar trace layer name

        Returns: (str) collar trace layer name

        """
        return ""

    def get_planned_trace_layer(self) -> QgsVectorLayer:
        """
        Return None for planned trace QgsVectorLayer :

        """
        return None

    def get_planned_trace_layer_name(self) -> str:
        """
        Get planned trace layer name

        Returns: (str) collar trace layer name

        """
        return ""

    def unselect_collar_by_id(self, hole_ids: List[str]) -> None:
        """
        Unselect collar by ID in collar layer

        Args:
            hole_ids: List[str]: selected collar id
        """
        collar_layer = self.get_collar_layer()
        if collar_layer is not None:
            in_ = ",".join(hole_ids)
            collar_layer.selectByExpression(
                f'"id" IN ({in_})', behavior=Qgis.SelectBehavior.RemoveFromSelection
            )
