# 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.complete_invitation_response import CompleteInvitationResponse
from ..types.invitation_details_response import InvitationDetailsResponse
from ..types.invitation_response import InvitationResponse
from .raw_client import AsyncRawCrewManagementInvitationsClient, RawCrewManagementInvitationsClient

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


class CrewManagementInvitationsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawCrewManagementInvitationsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawCrewManagementInvitationsClient
        """
        return self._raw_client

    def invite_user(
        self,
        organization_id: str,
        *,
        email: str,
        role_id: str,
        full_name: typing.Optional[str] = OMIT,
        send_invitation: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> InvitationResponse:
        """
        Invite a new user to join the organization.

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

        Args:
            organization_id: Organization ID
            request: Invitation request with email, role_id, and send_invitation flag
            db: Database session
            auth: Authenticated user

        Returns:
            Created invitation details

        Raises:
            ConflictException: If user already exists in organization
            ValidationException: If invalid email or role

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

        email : str
            Email address to invite

        role_id : str
            Role ID to assign

        full_name : typing.Optional[str]
            Full name of the invited user. Set on the user record immediately if provided.

        send_invitation : typing.Optional[bool]
            Whether to send invitation email. Must be explicitly set to true to trigger the email.

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

        Returns
        -------
        InvitationResponse
            Successful Response

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

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_invitations.invite_user(
            organization_id="organization_id",
            email="email",
            role_id="role_id",
        )
        """
        _response = self._raw_client.invite_user(
            organization_id,
            email=email,
            role_id=role_id,
            full_name=full_name,
            send_invitation=send_invitation,
            request_options=request_options,
        )
        return _response.data

    def get_invitation(
        self,
        organization_id: str,
        *,
        email: typing.Optional[str] = None,
        user_id: typing.Optional[str] = None,
        invitation_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> InvitationDetailsResponse:
        """
        Get pending invitation details including the invitation link.

        Provide ONE of: email, user_id, or invitation_id.

        Requires:
        - User must be authenticated
        - User must be a member of the organization

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

        email : typing.Optional[str]
            Email address to look up

        user_id : typing.Optional[str]
            User ID (usr_...)

        invitation_id : typing.Optional[str]
            Invitation ID (inv_...)

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

        Returns
        -------
        InvitationDetailsResponse
            Successful Response

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

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_invitations.get_invitation(
            organization_id="organization_id",
        )
        """
        _response = self._raw_client.get_invitation(
            organization_id, email=email, user_id=user_id, invitation_id=invitation_id, request_options=request_options
        )
        return _response.data

    def resend_invitation(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Resend invitation to a single user.

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

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)
        - Invitation must exist and not be accepted

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

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation already accepted

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

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) to resend invitation to

        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_invitations.resend_invitation(
            organization_id="organization_id",
            user_id="user_id",
        )
        """
        _response = self._raw_client.resend_invitation(organization_id, user_id, request_options=request_options)
        return _response.data

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

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

        Args:
            organization_id: Organization ID
            request: List of user IDs to resend invitations to
            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 resend invitations

        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_invitations.resend_invitations_bulk(
            organization_id="organization_id",
            user_ids=["user_ids"],
        )
        """
        _response = self._raw_client.resend_invitations_bulk(
            organization_id, user_ids=user_ids, request_options=request_options
        )
        return _response.data

    def validate_invitation(
        self, email_key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Validate an invitation by email key.

        This endpoint is public (no authentication required) for users
        accepting invitations.

        Args:
            email_key: Unique email key from invitation link
            db: Database session

        Returns:
            Invitation validation details

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired or already used

        Parameters
        ----------
        email_key : str

        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_invitations.validate_invitation(
            email_key="email_key",
        )
        """
        _response = self._raw_client.validate_invitation(email_key, request_options=request_options)
        return _response.data

    def accept_invitation(
        self, *, email_key: str, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Accept an invitation to join an organization.

        User must be authenticated.

        Args:
            email_key: Unique email key from invitation link
            db: Database session
            auth: Authenticated user

        Returns:
            Acceptance confirmation with organization details

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired or already used
            ConflictException: If user already member of organization

        Parameters
        ----------
        email_key : str
            Unique email key from invitation link

        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_invitations.accept_invitation(
            email_key="email_key",
        )
        """
        _response = self._raw_client.accept_invitation(email_key=email_key, request_options=request_options)
        return _response.data

    def complete_invitation(
        self, *, email_key: str, full_name: str, password: str, request_options: typing.Optional[RequestOptions] = None
    ) -> CompleteInvitationResponse:
        """
        Complete invitation by registering user and returning auth tokens.

        This is a public endpoint (no authentication required) that atomically:
        1. Validates the invitation
        2. Updates user with name and password
        3. Marks invitation as used
        4. Activates organization membership
        5. Returns JWT tokens for immediate login

        Args:
            request: Invitation completion request with email_key, full_name, password
            db: Database session

        Returns:
            Auth tokens and user info

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired, already used, or invalid password

        Parameters
        ----------
        email_key : str
            Invitation email key from the URL

        full_name : str
            User's full name

        password : str
            User's password

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

        Returns
        -------
        CompleteInvitationResponse
            Successful Response

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

        client = Aitronos(
            api_key="YOUR_API_KEY",
            token="YOUR_TOKEN",
        )
        client.crew_management_invitations.complete_invitation(
            email_key="email_key",
            full_name="full_name",
            password="password",
        )
        """
        _response = self._raw_client.complete_invitation(
            email_key=email_key, full_name=full_name, password=password, request_options=request_options
        )
        return _response.data

    def cancel_invitation(
        self, organization_id: str, invitation_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Cancel a pending invitation.

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

        Args:
            organization_id: Organization ID
            invitation_id: Invitation ID to cancel
            db: Database session
            auth: Authenticated user

        Raises:
            ResourceNotFoundException: If invitation not found
            AuthorizationException: If user lacks permissions

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

        invitation_id : str
            Invitation ID to cancel

        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_invitations.cancel_invitation(
            organization_id="organization_id",
            invitation_id="invitation_id",
        )
        """
        _response = self._raw_client.cancel_invitation(organization_id, invitation_id, request_options=request_options)
        return _response.data


class AsyncCrewManagementInvitationsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawCrewManagementInvitationsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawCrewManagementInvitationsClient
        """
        return self._raw_client

    async def invite_user(
        self,
        organization_id: str,
        *,
        email: str,
        role_id: str,
        full_name: typing.Optional[str] = OMIT,
        send_invitation: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> InvitationResponse:
        """
        Invite a new user to join the organization.

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

        Args:
            organization_id: Organization ID
            request: Invitation request with email, role_id, and send_invitation flag
            db: Database session
            auth: Authenticated user

        Returns:
            Created invitation details

        Raises:
            ConflictException: If user already exists in organization
            ValidationException: If invalid email or role

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

        email : str
            Email address to invite

        role_id : str
            Role ID to assign

        full_name : typing.Optional[str]
            Full name of the invited user. Set on the user record immediately if provided.

        send_invitation : typing.Optional[bool]
            Whether to send invitation email. Must be explicitly set to true to trigger the email.

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

        Returns
        -------
        InvitationResponse
            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_invitations.invite_user(
                organization_id="organization_id",
                email="email",
                role_id="role_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.invite_user(
            organization_id,
            email=email,
            role_id=role_id,
            full_name=full_name,
            send_invitation=send_invitation,
            request_options=request_options,
        )
        return _response.data

    async def get_invitation(
        self,
        organization_id: str,
        *,
        email: typing.Optional[str] = None,
        user_id: typing.Optional[str] = None,
        invitation_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> InvitationDetailsResponse:
        """
        Get pending invitation details including the invitation link.

        Provide ONE of: email, user_id, or invitation_id.

        Requires:
        - User must be authenticated
        - User must be a member of the organization

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

        email : typing.Optional[str]
            Email address to look up

        user_id : typing.Optional[str]
            User ID (usr_...)

        invitation_id : typing.Optional[str]
            Invitation ID (inv_...)

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

        Returns
        -------
        InvitationDetailsResponse
            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_invitations.get_invitation(
                organization_id="organization_id",
            )


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

    async def resend_invitation(
        self, organization_id: str, user_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Resend invitation to a single user.

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

        Requires:
        - User must be authenticated
        - User must be a member of the organization (any role)
        - Invitation must exist and not be accepted

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

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation already accepted

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

        user_id : str
            User ID (usr_...) or OrganizationUser ID (orgusr_...) to resend invitation to

        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_invitations.resend_invitation(
                organization_id="organization_id",
                user_id="user_id",
            )


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

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

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

        Args:
            organization_id: Organization ID
            request: List of user IDs to resend invitations to
            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 resend invitations

        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_invitations.resend_invitations_bulk(
                organization_id="organization_id",
                user_ids=["user_ids"],
            )


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

    async def validate_invitation(
        self, email_key: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Validate an invitation by email key.

        This endpoint is public (no authentication required) for users
        accepting invitations.

        Args:
            email_key: Unique email key from invitation link
            db: Database session

        Returns:
            Invitation validation details

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired or already used

        Parameters
        ----------
        email_key : str

        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_invitations.validate_invitation(
                email_key="email_key",
            )


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

    async def accept_invitation(
        self, *, email_key: str, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Accept an invitation to join an organization.

        User must be authenticated.

        Args:
            email_key: Unique email key from invitation link
            db: Database session
            auth: Authenticated user

        Returns:
            Acceptance confirmation with organization details

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired or already used
            ConflictException: If user already member of organization

        Parameters
        ----------
        email_key : str
            Unique email key from invitation link

        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_invitations.accept_invitation(
                email_key="email_key",
            )


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

    async def complete_invitation(
        self, *, email_key: str, full_name: str, password: str, request_options: typing.Optional[RequestOptions] = None
    ) -> CompleteInvitationResponse:
        """
        Complete invitation by registering user and returning auth tokens.

        This is a public endpoint (no authentication required) that atomically:
        1. Validates the invitation
        2. Updates user with name and password
        3. Marks invitation as used
        4. Activates organization membership
        5. Returns JWT tokens for immediate login

        Args:
            request: Invitation completion request with email_key, full_name, password
            db: Database session

        Returns:
            Auth tokens and user info

        Raises:
            ResourceNotFoundException: If invitation not found
            ValidationException: If invitation expired, already used, or invalid password

        Parameters
        ----------
        email_key : str
            Invitation email key from the URL

        full_name : str
            User's full name

        password : str
            User's password

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

        Returns
        -------
        CompleteInvitationResponse
            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_invitations.complete_invitation(
                email_key="email_key",
                full_name="full_name",
                password="password",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.complete_invitation(
            email_key=email_key, full_name=full_name, password=password, request_options=request_options
        )
        return _response.data

    async def cancel_invitation(
        self, organization_id: str, invitation_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Cancel a pending invitation.

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

        Args:
            organization_id: Organization ID
            invitation_id: Invitation ID to cancel
            db: Database session
            auth: Authenticated user

        Raises:
            ResourceNotFoundException: If invitation not found
            AuthorizationException: If user lacks permissions

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

        invitation_id : str
            Invitation ID to cancel

        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_invitations.cancel_invitation(
                organization_id="organization_id",
                invitation_id="invitation_id",
            )


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