import json
from dataclasses import dataclass
from functools import lru_cache

# PyQGIS
from qgis.PyQt.QtCore import QUrl

# plugin
from oslandia.constants import UTM_CONTENT_ISSUEBROWSER
from oslandia.helpdesk.gitlab_object import (
    PageLoadResult,
    get_nb_result_and_page_from_reply,
)
from oslandia.toolbelt import PlgLogger, PlgOptionsManager
from oslandia.toolbelt.network_manager import NetworkRequestsManager


@dataclass
class Members:
    id: int
    username: str
    name: str
    avatar_url: str


class MembersRequestManager:
    MAX_LIMIT = 50

    def get_base_url(self, project_id: int) -> str:
        """
        Get base url for members of a group

        Args:
            project_id: (int) project id

        Returns: url for members info

        """
        return f"{self.plg_settings.gitlab_api_url_base}/projects/{project_id}/members"

    def __init__(self):
        """
        Helper for stored_data request

        """
        self.log = PlgLogger().log
        self.ntwk_requester_blk = NetworkRequestsManager()
        self.plg_settings = PlgOptionsManager.get_plg_settings()

    @lru_cache
    def get_members_list(self, project: str) -> list[Members]:
        """
        Get list of members

        Args:
            group: (str) group id

        Returns: list of available members, raise ReadStoredDataException otherwise
        """
        self.log(f"{__name__}.get_members_list(project:{project})")

        result = []
        page_result = self.get_members_list_by_page(project, 1, self.MAX_LIMIT)
        nb_page = page_result.nb_page
        result += page_result.gitlab_object_list
        for page in range(2, nb_page + 1):
            page_result = self.get_members_list_by_page(project, page, self.MAX_LIMIT)
            result += page_result.gitlab_object_list

        return result

    def get_members_list_by_page(
        self, project_id: int, page: int = 1, limit: int = MAX_LIMIT
    ) -> PageLoadResult:
        """
        Get list of members

        Args:
            group: (str) group id
            page: (int) page number (start at 1)
            limit: (int)

        Returns: list of available members
        """

        # send request
        req_reply = self.ntwk_requester_blk.get_url(
            QUrl(
                f"{self.plg_settings.gitlab_api_url_base}/projects/{project_id}/members/all?page={page}&per_page={limit}"
            ),
            self.plg_settings.authentification_config_id,
            return_req_reply=True,
            caller=UTM_CONTENT_ISSUEBROWSER,
        )
        if req_reply:
            nb_result, nb_page = get_nb_result_and_page_from_reply(req_reply)
            data = json.loads(req_reply.content().data().decode("utf-8"))
            return PageLoadResult(
                nb_object=nb_result,
                nb_page=nb_page,
                page=page,
                gitlab_object_list=[
                    Members(
                        name=p_data["name"],
                        username=p_data["username"],
                        avatar_url=p_data["avatar_url"],
                        id=p_data["id"],
                    )
                    for p_data in data
                ],
            )

        return PageLoadResult(nb_object=0, nb_page=0, page=0, gitlab_object_list=[])
