# standard
import json

# PyQGIS
from qgis.PyQt.QtCore import QByteArray, QUrl

# plugin
from oslandia.constants import UTM_CONTENT_ISSUEBROWSER, UTM_MEDIUM_BACKGROUND
from oslandia.toolbelt.log_handler import PlgLogger
from oslandia.toolbelt.network_manager import NetworkRequestsManager
from oslandia.toolbelt.preferences import PlgOptionsManager


class GraphQLRequestManager:
    """
    Base class for GitLab GraphQL request
    """

    def __init__(self) -> None:
        """Constructor"""
        self.log = PlgLogger().log
        self.ntwk_requester_blk = NetworkRequestsManager()
        self.plg_settings = PlgOptionsManager.get_plg_settings()

    @staticmethod
    def _get_next_cursor(data: dict) -> str | None:
        """Get after cursor from data

        :param data: data dict
        :type data: dict
        :return: after cursor if available, None otherwise
        :rtype: Optional[str]
        """
        if data["pageInfo"]["hasNextPage"]:
            return data["pageInfo"]["endCursor"]
        return None

    def _post_query(self, query: str, variables: dict) -> dict | None:
        """Post GraphQL query with wanted variables

        :param query: GraphQL query
        :type query: str
        :param variables: GraphQL variable
        :type variables: Dict
        :return: query result if no error occurs, None otherwise
        :rtype: Optional[Dict]
        """
        # encode data
        data = QByteArray()
        data_map = {
            "query": query,
            "variables": variables,
        }

        data.append(json.dumps(data_map).encode("utf-8"))

        try:
            req_reply = self.ntwk_requester_blk.post_url(
                url=QUrl(self.plg_settings.gitlab_graphql_url),
                config_id=self.plg_settings.authentification_config_id,
                data=data,
                content_type_header="application/json",
                caller=UTM_CONTENT_ISSUEBROWSER,
                caller_medium=UTM_MEDIUM_BACKGROUND,
            )
            if req_reply:
                return json.loads(req_reply.data().decode("utf-8"))
            return None
        except ConnectionError:
            return None
