"""
Resources for fetching user data from the 42 API.
"""

from typing import Any, Self

from fortytwo.resources.resource import ListResource, Resource, ResourceTemplate
from fortytwo.resources.user.user import User


class GetUsersByCoalitionId(ListResource[User]):
    """
    Resource for fetching users by coalition ID.

    Returns a list of users belonging to the specified coalition.

    Args:
        coalition_id: The ID of the coalition whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/coalitions/%s/users"

    def __init__(self: Self, coalition_id: int) -> None:
        self.coalition_id = coalition_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.coalition_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByDashId(ListResource[User]):
    """
    Resource for fetching users by dash ID.

    Returns a list of users associated with the specified dash.

    Args:
        dash_id: The dash ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/dashes/%s/users"

    def __init__(self: Self, dash_id: int) -> None:
        self.dash_id = dash_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.dash_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByEventId(ListResource[User]):
    """
    Resource for fetching users by event ID.

    Returns a list of users associated with the specified event.

    Args:
        event_id: The event ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/events/%s/users"

    def __init__(self: Self, event_id: int) -> None:
        self.event_id = event_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.event_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByAccreditationId(ListResource[User]):
    """
    Resource for fetching users by accreditation ID.

    Returns a list of users associated with the specified accreditation.

    Args:
        accreditation_id: The accreditation ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/accreditations/%s/users"

    def __init__(self: Self, accreditation_id: int) -> None:
        self.accreditation_id = accreditation_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.accreditation_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByTeamId(ListResource[User]):
    """
    Resource for fetching users by team ID.

    Returns a list of users associated with the specified team.

    Args:
        team_id: The team ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/teams/%s/users"

    def __init__(self: Self, team_id: int) -> None:
        self.team_id = team_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.team_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByProjectId(ListResource[User]):
    """
    Resource for fetching users by project ID.

    Returns a list of users associated with the specified project.

    Args:
        project_id: The project ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/projects/%s/users"

    def __init__(self: Self, project_id: int) -> None:
        self.project_id = project_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.project_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByPartnershipId(ListResource[User]):
    """
    Resource for fetching users by partnership ID.

    Returns a list of users associated with the specified partnership.

    Args:
        partnership_id: The partnership ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/partnerships/%s/users"

    def __init__(self: Self, partnership_id: int) -> None:
        self.partnership_id = partnership_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.partnership_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByExpertiseId(ListResource[User]):
    """
    Resource for fetching users by expertise ID.

    Returns a list of users associated with the specified expertise.

    Args:
        expertise_id: The expertise ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/expertises/%s/users"

    def __init__(self: Self, expertise_id: int) -> None:
        self.expertise_id = expertise_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.expertise_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsers(ListResource[User]):
    """
    Resource for fetching all users.

    Returns a list of every users .
    """

    method: str = "GET"
    __url: str = "/users"

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByCursusId(ListResource[User]):
    """
    Resource for fetching users by cursus ID.

    Returns a list of users associated with the specified cursus.

    Args:
        cursus_id: The cursus ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/cursus/%s/users"

    def __init__(self: Self, cursus_id: int) -> None:
        self.cursus_id = cursus_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.cursus_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByCampusId(ListResource[User]):
    """
    Resource for fetching users by campus ID.

    Returns a list of users associated with the specified campus.

    Args:
        campus_id: The campus ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/campus/%s/users"

    def __init__(self: Self, campus_id: int) -> None:
        self.campus_id = campus_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.campus_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUserById(Resource[User]):
    """
    Resource for fetching a specific user by ID.

    Args:
        user_id: The ID of the user to fetch.
    """

    method: str = "GET"
    __url: str = "/users/%s"

    def __init__(self: Self, user_id: int) -> None:
        self.user_id = user_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.user_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return User.model_validate(response_data)


class GetUsersByAchievementId(ListResource[User]):
    """
    Resource for fetching users by achievement ID.

    Returns a list of users associated with the specified achievement.

    Args:
        achievement_id: The achievement ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/achievements/%s/users"

    def __init__(self: Self, achievement_id: int) -> None:
        self.achievement_id = achievement_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.achievement_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByTitleId(ListResource[User]):
    """
    Resource for fetching users by title ID.

    Returns a list of users associated with the specified title.

    Args:
        title_id: The title ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/titles/%s/users"

    def __init__(self: Self, title_id: int) -> None:
        self.title_id = title_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.title_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByQuestId(ListResource[User]):
    """
    Resource for fetching users by quest ID.

    Returns a list of users associated with the specified quest.

    Args:
        quest_id: The quest ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/quests/%s/users"

    def __init__(self: Self, quest_id: int) -> None:
        self.quest_id = quest_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.quest_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetUsersByGroupId(ListResource[User]):
    """
    Resource for fetching users by group ID.

    Returns a list of users associated with the specified group.

    Args:
        group_id: The group ID whose users to fetch.
    """

    method: str = "GET"
    __url: str = "/groups/%s/users"

    def __init__(self: Self, group_id: int) -> None:
        self.group_id = group_id

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url % self.group_id

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return [User.model_validate(user) for user in response_data]


class GetMe(Resource[User]):
    """
    Resource for fetching the authenticated user's information.

    Returns the user data from the /me endpoint.
    """

    method: str = "GET"
    __url: str = "/me"

    @property
    def url(self: Self) -> str:
        return self.config.request_endpoint + self.__url

    def parse_response(self: Self, response_data: Any) -> ResourceTemplate:
        return User.model_validate(response_data)
