import sqlalchemy
from qgis.PyQt.QtWidgets import QCheckBox
from sqlalchemy import create_engine

from openlog.datamodel.connection.openlog_connection import Connection
from openlog.gui.connection.connection_widget import ConnectionWidget
from openlog.plugins.connections.geotic.mssql_utils import (
    MSSQL_SECURE_CONNECTION_OPTION,
    get_connection_url,
)


class MssqlConnectionWidget(ConnectionWidget):
    def __init__(self, parent=None) -> None:
        self.secure_connection_checkbox = None
        super().__init__(parent)
        self.secure_connection_checkbox = QCheckBox(self.tr("Secure connection"), self)
        self.params_layout.addWidget(
            self.secure_connection_checkbox, self.params_layout.rowCount(), 0
        )

        self.secure_connection_checkbox.clicked.connect(
            lambda clicked: self.auth_group_box.setEnabled(not clicked)
        )
        self._load_connection()

    def _get_connection_type_name(self) -> str:
        """
        Returns connection type name for save in QgsSettings

        Returns: 'mssql'

        """
        return "mssql"

    def get_connection_model(self) -> Connection:
        """
        Return openlog connection from widget

        Returns: openlog connnection

        """
        result = super().get_connection_model()
        result.optional_params[
            MSSQL_SECURE_CONNECTION_OPTION
        ] = self.secure_connection_checkbox.isChecked()

        return result

    def set_connection_model(self, connection: Connection) -> None:
        """
        Define current widget parameters from openlog connection

        Args:
            connection: openlog connection
        """
        super().set_connection_model(connection)
        if self.secure_connection_checkbox:
            secure_connection = False
            if connection.optional_params and MSSQL_SECURE_CONNECTION_OPTION in list(
                connection.optional_params.keys()
            ):
                secure_connection = connection.optional_params[
                    MSSQL_SECURE_CONNECTION_OPTION
                ]
                if type(secure_connection) == str:
                    secure_connection = (
                        True if secure_connection.lower() == "true" else False
                    )
            self.secure_connection_checkbox.setChecked(secure_connection)
            self.auth_group_box.setEnabled(not secure_connection)

    def get_connection_object(self, connection: Connection):
        """
        Create a sqlalchemy connection.
        Raises InvalidConnection if connection invalid

        Returns: sqlalchemy connection

        """
        try:
            connection_url = get_connection_url(connection)
            engine = create_engine(connection_url)

            conn = engine.connect()
        except sqlalchemy.exc.OperationalError as exc:
            raise ConnectionWidget.InvalidConnection(exc)
        return conn
