from __future__ import annotations

from typing import TYPE_CHECKING

from fortytwo.parameter import Parameter, with_pagination
from fortytwo.resources.project_user.parameter import ProjectUserParameters
from fortytwo.resources.project_user.resource import (
    GetProjectUserById,
    GetProjectUsers,
    GetProjectUsersByProject,
    GetProjectUsersByUserId,
)


if TYPE_CHECKING:
    from fortytwo.core import ApiListResponse, ApiResponse, AsyncClient
    from fortytwo.resources.project_user.project_user import ProjectUser


class AsyncProjectUserManager:
    """
    Asynchronous manager for project user-related API operations.
    """

    parameters = ProjectUserParameters

    def __init__(self, client: AsyncClient) -> None:
        self.__client = client

    async def get_by_id(self, project_user_id: int, *params: Parameter) -> ApiResponse[ProjectUser]:
        """
        Get a project user by ID.

        Args:
            project_user_id: The project user ID to fetch
            *params: Additional request parameters

        Returns:
            ProjectUser object

        Raises:
            FortyTwoNotFoundException: If project user is not found
            FortyTwoRequestException: If the request fails
        """
        return await self.__client.request(GetProjectUserById(project_user_id), *params)

    @with_pagination
    async def get_all(
        self,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ProjectUser]:
        """
        Get all project users.

        Args:
            *params: Additional request parameters
            page: Page number to fetch (1-indexed)
            page_size: Number of items per page (1-100)

        Returns:
            List of ProjectUser objects

        Raises:
            FortyTwoRequestException: If the request fails
        """
        return await self.__client.request(GetProjectUsers(), *params)

    @with_pagination
    async def get_by_project_id(
        self,
        project_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ProjectUser]:
        """
        Get all project users for a specific project ID.

        Args:
            project_id: The project ID to fetch project users for
            *params: Additional request parameters
            page: Page number to fetch (1-indexed)
            page_size: Number of items per page (1-100)

        Returns:
            List of ProjectUser objects

        Raises:
            FortyTwoRequestException: If the request fails
        """
        return await self.__client.request(GetProjectUsersByProject(project_id), *params)

    @with_pagination
    async def get_by_user_id(
        self,
        user_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ProjectUser]:
        """
        Get all project users for a specific user ID.

        Args:
            user_id: The user ID to fetch project users for
            *params: Additional request parameters
            page: Page number to fetch (1-indexed)
            page_size: Number of items per page (1-100)

        Returns:
            List of ProjectUser objects

        Raises:
            FortyTwoRequestException: If the request fails
        """
        return await self.__client.request(GetProjectUsersByUserId(user_id), *params)
