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.spatialite.spatialite_connection import (
    SpatialiteConnection,
)


class PivotSpatialiteLayersInterface(LayersInterface):
    def __init__(
        self, connection: Connection, spatialite_connection: SpatialiteConnection
    ):
        """
        Implementation of LayersInterface with a pivot spatialite connection

        Methods are updated to :
        - set layers read only
        - add database used in connection in layers name

        Args:
            connection: Connection used
            spatialite_connection: SpatialiteConnection used for pivot
        """
        super().__init__()
        self._connection = connection
        self._spatialite_connection = spatialite_connection

    def splitted_trace_layer_available(self):
        return True

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

        In acquire we use pivot spatialite database to store collar geometry

        """
        if self.collar_layer is None:
            self.collar_layer = (
                self._spatialite_connection.get_layers_iface().get_collar_layer()
            )
            self.collar_layer.setReadOnly(True)
            self.collar_layer.setName(self.get_collar_layer_name())
        return self.collar_layer

    def get_planned_collar_layer(self) -> QgsVectorLayer:
        """
        Return planned collar QgsVectorLayer

        In acquire we use pivot spatialite database to store collar geometry

        """
        if self.planned_collar_layer is None:
            self.planned_collar_layer = (
                self._spatialite_connection.get_layers_iface().get_planned_collar_layer()
            )
            self.planned_collar_layer.setReadOnly(True)
            self.planned_collar_layer.setName(self.get_planned_collar_layer_name())
        return self.planned_collar_layer

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

        Returns: (str) collar layer name

        """
        return "Collar - [{0}] (pivot spatialite)".format(self._connection.database)

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

        Returns: (str) collar layer name

        """
        return "Planned collar - [{0}] (pivot spatialite)".format(
            self._connection.database
        )

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

        In acquire we use pivot spatialite database to store collar trace geometry

        """
        if self.collar_trace_layer is None:
            self.collar_trace_layer = (
                self._spatialite_connection.get_layers_iface().get_collar_trace_layer()
            )
            self.collar_trace_layer.setReadOnly(True)
            self.collar_trace_layer.setName(self.get_collar_trace_layer_name())
        return self.collar_trace_layer

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

        In acquire we use pivot spatialite database to store planned trace geometry

        """
        if self.planned_trace_layer is None:
            self.planned_trace_layer = (
                self._spatialite_connection.get_layers_iface().get_planned_trace_layer()
            )
            self.planned_trace_layer.setReadOnly(True)
            self.planned_trace_layer.setName(self.get_planned_trace_layer_name())
        return self.planned_trace_layer

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

        Returns: (str) collar trace layer name

        """
        return "Trace - [{0}] (pivot spatialite)".format(self._connection.database)

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

        Returns: (str) collar trace layer name

        """
        return "Planned trace - [{0}] (pivot spatialite)".format(
            self._connection.database
        )

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

        In spatialite collar trace geometry is available in collar geom_trace column

        """
        layer_name = self.get_splitted_trace_layer_name(
            column_config, planned, barcharts
        )
        id_name = f"{column_config.assay_name}_{column_config.column.name}"
        suffix = "planned_trace" if planned else "trace"

        uri = self._get_datasource_uri()
        uri.setDataSource("", f"{id_name}_{suffix}", "geom_interval")
        self.splitted_trace_layer = QgsVectorLayer(
            uri.uri(False), layer_name, "spatialite"
        )
        self._set_clamping(self.splitted_trace_layer)
        return self.splitted_trace_layer

    def _get_datasource_uri(self) -> QgsDataSourceUri:
        """
        Get a QgsDataSourceUri from spatialite file

        Returns: QgsDataSourceUri with current connection parameters

        """
        uri = QgsDataSourceUri()
        uri.setDatabase(str(self._spatialite_connection._file_path))
        return uri
