from qgis.core import QgsDataSourceUri, QgsVectorLayer

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 XplordbLayersInterface(LayersInterface):
    def __init__(self, connection: Connection):
        """
        Implements LayersInterface for XplordbConnection

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

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

        In xplordb collar geometry is available in dh.collar geom column

        """
        if self.collar_layer is None:
            uri = self._get_datasource_uri()
            uri.setDataSource(
                "",
                "(select * from dh.collar left join dh.metadata using(hole_id))",
                "geom",
                "",
                "hole_id",
            )
            self.collar_layer = QgsVectorLayer(
                uri.uri(False), self.get_collar_layer_name(), "postgres"
            )
            self._set_clamping(self.collar_layer)
        return self.collar_layer

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

        Returns: (str) collar layer name

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

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

        In xplordb collar trace geometry is available in dh.collar geom_trace column

        """
        if self.collar_trace_layer is None:
            uri = self._get_datasource_uri()
            uri.setDataSource("display", "display_collar", "effective_geom")
            self.collar_trace_layer = QgsVectorLayer(
                uri.uri(False), self.get_collar_trace_layer_name(), "postgres"
            )
            self._set_clamping(self.collar_trace_layer)
        return self.collar_trace_layer

    def get_planned_trace_layer_name(self) -> str:
        return self.tr(f"Planned trace - [{self._connection.database}]")

    def get_planned_trace_layer(self) -> QgsVectorLayer:
        """
        Return plannedf trace QgsVectorLayer

        In spatialite collar trace geometry is available in collar geom_trace column

        """
        if self.planned_trace_layer is None:
            uri = self._get_datasource_uri()
            uri.setDataSource("display", "display_collar", "planned_geom")
            self.planned_trace_layer = QgsVectorLayer(
                uri.uri(False), self.get_planned_trace_layer_name(), "postgres"
            )
            self._set_clamping(self.planned_trace_layer)
        return self.planned_trace_layer

    def get_splitted_trace_layer(
        self, name: str = "", planned: bool = False
    ) -> QgsVectorLayer:
        """
        Return splitted trace QgsVectorLayer

        In spatialite collar trace geometry is available in collar geom_trace column

        """
        suffix = "planned_trace" if planned else "trace"

        uri = self._get_datasource_uri()
        uri.setDataSource("display", f"{name}_{suffix}", "geom_interval")
        self.splitted_trace_layer = QgsVectorLayer(
            uri.uri(False), f"{name}_{suffix}", "postgres"
        )
        self._set_clamping(self.splitted_trace_layer)
        return self.splitted_trace_layer

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

        Returns: (str) collar trace layer name

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

    def _get_datasource_uri(self) -> QgsDataSourceUri:
        """
        Get a QgsDataSourceUri from current connection parameters

        Returns: QgsDataSourceUri for with current connection parameters

        """
        return create_datasource_uri(self._connection)
