# This file was auto-generated by Fern from our API Definition.

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.bulk_operation_response import BulkOperationResponse
from ..types.member_list_response import MemberListResponse
from ..types.member_response import MemberResponse
from ..types.status_summary_response import StatusSummaryResponse
from .raw_client import AsyncRawCrewManagementMembersClient, RawCrewManagementMembersClient

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class CrewManagementMembersClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawCrewManagementMembersClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawCrewManagementMembersClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawCrewManagementMembersClient
        """
        return self._raw_client

    def list_members(
        self,
        organization_id: str,
        *,
        skip: typing.Optional[int] = OMIT,
        take: typing.Optional[int] = OMIT,
        search_term: typing.Optional[str] = OMIT,
        role_id: typing.Optional[str] = OMIT,
        status_id: typing.Optional[str] = OMIT,
        sort_column: typing.Optional[str] = OMIT,
        sort_direction: typing.Optional[str] = OMIT,
        include_inactive: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MemberListResponse:
        """
        Get paginated list of organization members with filtering and sorting.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            request: Pagination and filter parameters
            db: Database session
            auth: Authenticated user

        Returns:
            Paginated list of members with total count

        Parameters
        ----------
        organization_id : str
            Organization ID to list members from

        skip : typing.Optional[int]
            Number of records to skip

        take : typing.Optional[int]
            Number of records to return (max 500)

        search_term : typing.Optional[str]
            Search across full_name, email, and username

        role_id : typing.Optional[str]
            Filter by role ID

        status_id : typing.Optional[str]
            Filter by status ID

        sort_column : typing.Optional[str]
            Field to sort by (full_name, email, role, status, created_at, last_modified_at)

        sort_direction : typing.Optional[str]
            Sort direction (asc or desc)

        include_inactive : typing.Optional[bool]
            Include soft-deleted/inactive members

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberListResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.list_members(
            organization_id="organization_id",
        )
        """
        _response = self._raw_client.list_members(
            organization_id,
            skip=skip,
            take=take,
            search_term=search_term,
            role_id=role_id,
            status_id=status_id,
            sort_column=sort_column,
            sort_direction=sort_direction,
            include_inactive=include_inactive,
            request_options=request_options,
        )
        return _response.data

    def get_member_ids(
        self,
        organization_id: str,
        *,
        include_deleted: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[str]:
        """
        Get list of all member user IDs in the organization.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            db: Database session
            auth: Authenticated user
            include_deleted: Whether to include soft-deleted members

        Returns:
            List of user IDs

        Parameters
        ----------
        organization_id : str
            Organization ID to get member IDs from

        include_deleted : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[str]
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.get_member_ids(
            organization_id="organization_id",
        )
        """
        _response = self._raw_client.get_member_ids(
            organization_id, include_deleted=include_deleted, request_options=request_options
        )
        return _response.data

    def get_members_by_ids(
        self,
        organization_id: str,
        *,
        request: typing.Dict[str, typing.Any],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Get organization members by specific user IDs.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            request: Dictionary with 'user_ids' list
            db: Database session
            auth: Authenticated user

        Returns:
            Dictionary with users list, total count, and requested IDs

        Parameters
        ----------
        organization_id : str
            Organization ID to get members from

        request : typing.Dict[str, typing.Any]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Any]
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.get_members_by_ids(
            organization_id="organization_id",
            request={"key": "value"},
        )
        """
        _response = self._raw_client.get_members_by_ids(
            organization_id, request=request, request_options=request_options
        )
        return _response.data

    def get_status_summary(
        self, organization_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> StatusSummaryResponse:
        """
        Get aggregated member counts grouped by status.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            db: Database session
            auth: Authenticated user

        Returns:
            Status summary with counts for each status

        Parameters
        ----------
        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusSummaryResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.get_status_summary(
            organization_id="organization_id",
        )
        """
        _response = self._raw_client.get_status_summary(organization_id, request_options=request_options)
        return _response.data

    def get_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> MemberResponse:
        """
        Get details of a specific organization member.

        Accepts either:
        - User ID (usr_...) - will look up by user_id + organization_id
        - OrganizationUser ID (orgusr_...) - will look up directly by organization_user_id

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Returns:
            Member details

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to retrieve

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.get_member(
            organization_id="organization_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.get_member(organization_id, user_id, request_options=request_options)
        return _response.data

    def update_member(
        self,
        organization_id: str,
        user_id: str,
        *,
        role_id: typing.Optional[str] = OMIT,
        status_id: typing.Optional[str] = OMIT,
        first_name: typing.Optional[str] = OMIT,
        last_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MemberResponse:
        """
        Update a member's role and/or status.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role for status changes)
        - User must have Admin or Owner role (for role changes only)
        - Cannot change owner's role
        - Cannot set owner to inactive status

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            request: Update request with role_id and/or status_id
            db: Database session
            auth: Authenticated user

        Returns:
            Updated member details

        Raises:
            ValidationException: If attempting to update owner inappropriately
            AuthorizationException: If non-admin/owner attempts role change
            ResourceNotFoundException: If member, role, or status not found

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to update

        role_id : typing.Optional[str]
            New role ID

        status_id : typing.Optional[str]
            New status ID

        first_name : typing.Optional[str]
            Updated first name

        last_name : typing.Optional[str]
            Updated last name

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.update_member(
            organization_id="organization_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.update_member(
            organization_id,
            user_id,
            role_id=role_id,
            status_id=status_id,
            first_name=first_name,
            last_name=last_name,
            request_options=request_options,
        )
        return _response.data

    def delete_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Soft delete a single organization member.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Cannot delete organization owner

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Raises:
            ValidationException: If attempting to delete owner
            ResourceNotFoundException: If member not found

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.delete_member(
            organization_id="organization_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.delete_member(organization_id, user_id, request_options=request_options)
        return _response.data

    def delete_members_bulk(
        self,
        organization_id: str,
        *,
        user_ids: typing.Sequence[str],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkOperationResponse:
        """
        Bulk delete organization members with partial failure handling.

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Organization owner will be skipped automatically

        Args:
            organization_id: Organization ID
            request: List of user IDs to delete
            db: Database session
            auth: Authenticated user

        Returns:
            Bulk operation response with success/failure counts

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_ids : typing.Sequence[str]
            List of user IDs to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BulkOperationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.delete_members_bulk(
            organization_id="organization_id",
            user_ids=["user_ids"],
        )
        """
        _response = self._raw_client.delete_members_bulk(
            organization_id, user_ids=user_ids, request_options=request_options
        )
        return _response.data

    def restore_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Restore a soft-deleted organization member.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Member must be soft-deleted

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Raises:
            ResourceNotFoundException: If member not found
            ValidationException: If member is not deleted

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to restore

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.restore_member(
            organization_id="organization_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.restore_member(organization_id, user_id, request_options=request_options)
        return _response.data

    def change_status_bulk(
        self,
        organization_id: str,
        *,
        user_ids: typing.Sequence[str],
        status_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkOperationResponse:
        """
        Bulk change member status with partial failure handling.

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Organization owner will be skipped if setting inactive status

        Args:
            organization_id: Organization ID
            request: List of user IDs and new status ID
            db: Database session
            auth: Authenticated user

        Returns:
            Bulk operation response with success/failure counts

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_ids : typing.Sequence[str]
            List of user IDs to update

        status_id : str
            New status ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BulkOperationResponse
            Successful Response

        Examples
        --------
        from aitronos import Aitronos

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_members.change_status_bulk(
            organization_id="organization_id",
            user_ids=["user_ids"],
            status_id="status_id",
        )
        """
        _response = self._raw_client.change_status_bulk(
            organization_id, user_ids=user_ids, status_id=status_id, request_options=request_options
        )
        return _response.data


class AsyncCrewManagementMembersClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawCrewManagementMembersClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawCrewManagementMembersClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawCrewManagementMembersClient
        """
        return self._raw_client

    async def list_members(
        self,
        organization_id: str,
        *,
        skip: typing.Optional[int] = OMIT,
        take: typing.Optional[int] = OMIT,
        search_term: typing.Optional[str] = OMIT,
        role_id: typing.Optional[str] = OMIT,
        status_id: typing.Optional[str] = OMIT,
        sort_column: typing.Optional[str] = OMIT,
        sort_direction: typing.Optional[str] = OMIT,
        include_inactive: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MemberListResponse:
        """
        Get paginated list of organization members with filtering and sorting.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            request: Pagination and filter parameters
            db: Database session
            auth: Authenticated user

        Returns:
            Paginated list of members with total count

        Parameters
        ----------
        organization_id : str
            Organization ID to list members from

        skip : typing.Optional[int]
            Number of records to skip

        take : typing.Optional[int]
            Number of records to return (max 500)

        search_term : typing.Optional[str]
            Search across full_name, email, and username

        role_id : typing.Optional[str]
            Filter by role ID

        status_id : typing.Optional[str]
            Filter by status ID

        sort_column : typing.Optional[str]
            Field to sort by (full_name, email, role, status, created_at, last_modified_at)

        sort_direction : typing.Optional[str]
            Sort direction (asc or desc)

        include_inactive : typing.Optional[bool]
            Include soft-deleted/inactive members

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberListResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.list_members(
                organization_id="organization_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.list_members(
            organization_id,
            skip=skip,
            take=take,
            search_term=search_term,
            role_id=role_id,
            status_id=status_id,
            sort_column=sort_column,
            sort_direction=sort_direction,
            include_inactive=include_inactive,
            request_options=request_options,
        )
        return _response.data

    async def get_member_ids(
        self,
        organization_id: str,
        *,
        include_deleted: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[str]:
        """
        Get list of all member user IDs in the organization.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            db: Database session
            auth: Authenticated user
            include_deleted: Whether to include soft-deleted members

        Returns:
            List of user IDs

        Parameters
        ----------
        organization_id : str
            Organization ID to get member IDs from

        include_deleted : typing.Optional[bool]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[str]
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.get_member_ids(
                organization_id="organization_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_member_ids(
            organization_id, include_deleted=include_deleted, request_options=request_options
        )
        return _response.data

    async def get_members_by_ids(
        self,
        organization_id: str,
        *,
        request: typing.Dict[str, typing.Any],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Get organization members by specific user IDs.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            request: Dictionary with 'user_ids' list
            db: Database session
            auth: Authenticated user

        Returns:
            Dictionary with users list, total count, and requested IDs

        Parameters
        ----------
        organization_id : str
            Organization ID to get members from

        request : typing.Dict[str, typing.Any]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.get_members_by_ids(
                organization_id="organization_id",
                request={"key": "value"},
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_members_by_ids(
            organization_id, request=request, request_options=request_options
        )
        return _response.data

    async def get_status_summary(
        self, organization_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> StatusSummaryResponse:
        """
        Get aggregated member counts grouped by status.

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            db: Database session
            auth: Authenticated user

        Returns:
            Status summary with counts for each status

        Parameters
        ----------
        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusSummaryResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.get_status_summary(
                organization_id="organization_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_status_summary(organization_id, request_options=request_options)
        return _response.data

    async def get_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> MemberResponse:
        """
        Get details of a specific organization member.

        Accepts either:
        - User ID (usr_...) - will look up by user_id + organization_id
        - OrganizationUser ID (orgusr_...) - will look up directly by organization_user_id

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Returns:
            Member details

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to retrieve

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.get_member(
                organization_id="organization_id",
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_member(organization_id, user_id, request_options=request_options)
        return _response.data

    async def update_member(
        self,
        organization_id: str,
        user_id: str,
        *,
        role_id: typing.Optional[str] = OMIT,
        status_id: typing.Optional[str] = OMIT,
        first_name: typing.Optional[str] = OMIT,
        last_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MemberResponse:
        """
        Update a member's role and/or status.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role for status changes)
        - User must have Admin or Owner role (for role changes only)
        - Cannot change owner's role
        - Cannot set owner to inactive status

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            request: Update request with role_id and/or status_id
            db: Database session
            auth: Authenticated user

        Returns:
            Updated member details

        Raises:
            ValidationException: If attempting to update owner inappropriately
            AuthorizationException: If non-admin/owner attempts role change
            ResourceNotFoundException: If member, role, or status not found

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to update

        role_id : typing.Optional[str]
            New role ID

        status_id : typing.Optional[str]
            New status ID

        first_name : typing.Optional[str]
            Updated first name

        last_name : typing.Optional[str]
            Updated last name

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        MemberResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.update_member(
                organization_id="organization_id",
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update_member(
            organization_id,
            user_id,
            role_id=role_id,
            status_id=status_id,
            first_name=first_name,
            last_name=last_name,
            request_options=request_options,
        )
        return _response.data

    async def delete_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Soft delete a single organization member.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Cannot delete organization owner

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Raises:
            ValidationException: If attempting to delete owner
            ResourceNotFoundException: If member not found

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.delete_member(
                organization_id="organization_id",
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete_member(organization_id, user_id, request_options=request_options)
        return _response.data

    async def delete_members_bulk(
        self,
        organization_id: str,
        *,
        user_ids: typing.Sequence[str],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkOperationResponse:
        """
        Bulk delete organization members with partial failure handling.

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Organization owner will be skipped automatically

        Args:
            organization_id: Organization ID
            request: List of user IDs to delete
            db: Database session
            auth: Authenticated user

        Returns:
            Bulk operation response with success/failure counts

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_ids : typing.Sequence[str]
            List of user IDs to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BulkOperationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.delete_members_bulk(
                organization_id="organization_id",
                user_ids=["user_ids"],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete_members_bulk(
            organization_id, user_ids=user_ids, request_options=request_options
        )
        return _response.data

    async def restore_member(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Restore a soft-deleted organization member.

        Accepts either:
        - User ID (usr_...)
        - OrganizationUser ID (orgusr_...)

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Member must be soft-deleted

        Args:
            organization_id: Organization ID
            user_id: User ID (usr_...) or OrganizationUser ID (orgusr_...)
            db: Database session
            auth: Authenticated user

        Raises:
            ResourceNotFoundException: If member not found
            ValidationException: If member is not deleted

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) of the member to restore

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.restore_member(
                organization_id="organization_id",
                user_id="user_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.restore_member(organization_id, user_id, request_options=request_options)
        return _response.data

    async def change_status_bulk(
        self,
        organization_id: str,
        *,
        user_ids: typing.Sequence[str],
        status_id: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> BulkOperationResponse:
        """
        Bulk change member status with partial failure handling.

        Requires:
        - User must be authenticated
        - User must be a member of the organization
        - User must have Admin or Owner role
        - Organization owner will be skipped if setting inactive status

        Args:
            organization_id: Organization ID
            request: List of user IDs and new status ID
            db: Database session
            auth: Authenticated user

        Returns:
            Bulk operation response with success/failure counts

        Parameters
        ----------
        organization_id : str
            Organization ID

        user_ids : typing.Sequence[str]
            List of user IDs to update

        status_id : str
            New status ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        BulkOperationResponse
            Successful Response

        Examples
        --------
        import asyncio

        from aitronos import AsyncAitronos

        client = AsyncAitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.crew_management_members.change_status_bulk(
                organization_id="organization_id",
                user_ids=["user_ids"],
                status_id="status_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.change_status_bulk(
            organization_id, user_ids=user_ids, status_id=status_id, request_options=request_options
        )
        return _response.data
