from __future__ import annotations

from typing import TYPE_CHECKING

from fortytwo.parameter import Parameter, with_pagination
from fortytwo.resources.scale_team.parameter import ScaleTeamParameters
from fortytwo.resources.scale_team.resource import (
    GetMyScaleTeams,
    GetMyScaleTeamsAsCorrected,
    GetMyScaleTeamsAsCorrector,
    GetScaleTeamById,
    GetScaleTeamByProjectSessionIdAndId,
    GetScaleTeams,
    GetScaleTeamsByProjectId,
    GetScaleTeamsByProjectSessionId,
    GetScaleTeamsByUserId,
    GetScaleTeamsByUserIdAsCorrected,
    GetScaleTeamsByUserIdAsCorrector,
)

if TYPE_CHECKING:
    from fortytwo.core import ApiListResponse, ApiResponse, Client
    from fortytwo.resources.scale_team.scale_team import ScaleTeam


class SyncScaleTeamManager:
    """
    Synchronous manager for scale team-related API operations.
    """

    parameters = ScaleTeamParameters

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

    @with_pagination
    def get_all(
        self,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams.

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

        Returns:
            List of ScaleTeam objects

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

    def get_by_id(self, scale_team_id: int, *params: Parameter) -> ApiResponse[ScaleTeam]:
        """
        Get a scale team by ID.

        Args:
            scale_team_id: The scale team ID to fetch
            *params: Additional request parameters

        Returns:
            ScaleTeam object

        Raises:
            FortyTwoNotFoundException: If scale team is not found
            FortyTwoRequestException: If the request fails
        """
        return self.__client.request(GetScaleTeamById(scale_team_id), *params)

    @with_pagination
    def get_by_project_session_id(
        self,
        project_session_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams for a given project session.

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

        Returns:
            List of ScaleTeam objects

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

    def get_by_project_session_id_and_id(
        self,
        project_session_id: int,
        scale_team_id: int,
        *params: Parameter,
    ) -> ApiResponse[ScaleTeam]:
        """
        Get a specific scale team within a project session.

        Args:
            project_session_id: The project session ID
            scale_team_id: The scale team ID to fetch
            *params: Additional request parameters

        Returns:
            ScaleTeam object

        Raises:
            FortyTwoNotFoundException: If scale team is not found
            FortyTwoRequestException: If the request fails
        """
        return self.__client.request(
            GetScaleTeamByProjectSessionIdAndId(project_session_id, scale_team_id),
            *params,
        )

    @with_pagination
    def get_by_project_id(
        self,
        project_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams for a given project.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_by_user_id(
        self,
        user_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams for a given user.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_by_user_id_as_corrector(
        self,
        user_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams where a user is the corrector.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_by_user_id_as_corrected(
        self,
        user_id: int,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get all scale teams where a user is corrected.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_my_scale_teams(
        self,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get the authenticated user's scale teams.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_my_scale_teams_as_corrector(
        self,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get the authenticated user's scale teams as corrector.

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

        Returns:
            List of ScaleTeam objects

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

    @with_pagination
    def get_my_scale_teams_as_corrected(
        self,
        *params: Parameter,
        page: int | None = None,
        page_size: int | None = None,
    ) -> ApiListResponse[ScaleTeam]:
        """
        Get the authenticated user's scale teams as corrected.

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

        Returns:
            List of ScaleTeam objects

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