# This file is auto-generated by oagen. Do not edit.

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union

if TYPE_CHECKING:
    from .._client import AsyncWorkOSClient, WorkOSClient

from .._types import RequestOptions, enum_value, NOT_GIVEN, NotGiven
from .models import (
    AuditLogConfiguration,
    Organization,
    OrganizationAuthorizedConnectApplicationListData,
    OrganizationDomainData,
)
from workos.common.models.pagination_order import PaginationOrder
from .._pagination import AsyncPage, SyncPage


class Organizations:
    """Organizations API resources."""

    def __init__(self, client: "WorkOSClient") -> None:
        self._client = client

    def list_organizations(
        self,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        domains: Optional[List[str]] = None,
        search: Optional[str] = None,
        request_options: Optional[RequestOptions] = None,
    ) -> SyncPage[Organization]:
        """List Organizations

        Get a list of all of your existing organizations matching the criteria specified.

        Args:
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            domains: The domains of an Organization. Any Organization with a matching domain will be returned.
            search: Searchable text for an Organization. Matches against the organization name.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            SyncPage[Organization]

        Raises:
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
                "domains": ",".join(str(v) for v in domains)
                if domains is not None
                else None,
                "search": search,
            }.items()
            if v is not None
        }
        return self._client.request_page(
            method="get",
            path=("organizations",),
            model=Organization,
            params=params,
            request_options=request_options,
        )

    def create_organization(
        self,
        *,
        name: str,
        allow_profiles_outside_organization: Optional[bool] = None,
        domains: Optional[List[str]] = None,
        domain_data: Optional[List[OrganizationDomainData]] = None,
        metadata: Union[Dict[str, str], None, NotGiven] = NOT_GIVEN,
        external_id: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Create an Organization

        Creates a new organization in the current environment.

        Args:
            name: The name of the organization.
            allow_profiles_outside_organization: Whether the organization allows profiles from outside the organization to sign in.
            domains: The domains associated with the organization. Deprecated in favor of `domain_data`.
            domain_data: The domains associated with the organization, including verification state.
            metadata: Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization.
            external_id: An external identifier for the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            BadRequestError: If the request is malformed (400).
            ConflictError: If a conflict occurs (409).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
                "allow_profiles_outside_organization": allow_profiles_outside_organization,
                "domains": domains,
                "domain_data": [item.to_dict() for item in domain_data]
                if domain_data is not None
                else None,
            }.items()
            if v is not None
        }
        if not isinstance(metadata, NotGiven):
            body["metadata"] = metadata
        if not isinstance(external_id, NotGiven):
            body["external_id"] = external_id
        return self._client.request(
            method="post",
            path=("organizations",),
            body=body,
            model=Organization,
            request_options=request_options,
        )

    def get_organization_by_external_id(
        self,
        external_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Get an Organization by External ID

        Get the details of an existing organization by an [external identifier](https://workos.com/docs/authkit/metadata/external-identifiers).

        Args:
            external_id: The external ID of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return self._client.request(
            method="get",
            path=("organizations", "external_id", str(external_id)),
            model=Organization,
            request_options=request_options,
        )

    def get_organization(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Get an Organization

        Get the details of an existing organization.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return self._client.request(
            method="get",
            path=("organizations", str(id)),
            model=Organization,
            request_options=request_options,
        )

    def update_organization(
        self,
        id: str,
        *,
        name: Optional[str] = None,
        allow_profiles_outside_organization: Optional[bool] = None,
        domains: Optional[List[str]] = None,
        domain_data: Optional[List[OrganizationDomainData]] = None,
        stripe_customer_id: Optional[str] = None,
        metadata: Union[Dict[str, str], None, NotGiven] = NOT_GIVEN,
        external_id: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Update an Organization

        Updates an organization in the current environment.

        Args:
            id: Unique identifier of the Organization.
            name: The name of the organization.
            allow_profiles_outside_organization: Whether the organization allows profiles from outside the organization to sign in.
            domains: (deprecated) The domains associated with the organization. Deprecated in favor of `domain_data`.
            domain_data: The domains associated with the organization, including verification state.
            stripe_customer_id: The Stripe customer ID associated with the organization.
            metadata: Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization.
            external_id: An external identifier for the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            ConflictError: If a conflict occurs (409).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
                "allow_profiles_outside_organization": allow_profiles_outside_organization,
                "domains": domains,
                "domain_data": [item.to_dict() for item in domain_data]
                if domain_data is not None
                else None,
                "stripe_customer_id": stripe_customer_id,
            }.items()
            if v is not None
        }
        if not isinstance(metadata, NotGiven):
            body["metadata"] = metadata
        if not isinstance(external_id, NotGiven):
            body["external_id"] = external_id
        return self._client.request(
            method="put",
            path=("organizations", str(id)),
            body=body,
            model=Organization,
            request_options=request_options,
        )

    def delete_organization(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Delete an Organization

        Permanently deletes an organization in the current environment. It cannot be undone.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        self._client.request(
            method="delete",
            path=("organizations", str(id)),
            request_options=request_options,
        )

    def get_audit_log_configuration(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> AuditLogConfiguration:
        """Get Audit Log Configuration

        Get the unified view of audit log trail and stream configuration for an organization.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AuditLogConfiguration

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return self._client.request(
            method="get",
            path=("organizations", str(id), "audit_log_configuration"),
            model=AuditLogConfiguration,
            request_options=request_options,
        )

    def list_authorized_applications(
        self,
        organization_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> SyncPage[OrganizationAuthorizedConnectApplicationListData]:
        """List authorized applications

        Get a list of all Connect applications that users in the organization have authorized.

        Args:
            organization_id: The ID of the organization.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            SyncPage[OrganizationAuthorizedConnectApplicationListData]

        Raises:
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return self._client.request_page(
            method="get",
            path=("organizations", str(organization_id), "authorized_applications"),
            model=OrganizationAuthorizedConnectApplicationListData,
            params=params,
            request_options=request_options,
        )


class AsyncOrganizations:
    """Organizations API resources (async)."""

    def __init__(self, client: "AsyncWorkOSClient") -> None:
        self._client = client

    async def list_organizations(
        self,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        domains: Optional[List[str]] = None,
        search: Optional[str] = None,
        request_options: Optional[RequestOptions] = None,
    ) -> AsyncPage[Organization]:
        """List Organizations

        Get a list of all of your existing organizations matching the criteria specified.

        Args:
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            domains: The domains of an Organization. Any Organization with a matching domain will be returned.
            search: Searchable text for an Organization. Matches against the organization name.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AsyncPage[Organization]

        Raises:
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
                "domains": ",".join(str(v) for v in domains)
                if domains is not None
                else None,
                "search": search,
            }.items()
            if v is not None
        }
        return await self._client.request_page(
            method="get",
            path=("organizations",),
            model=Organization,
            params=params,
            request_options=request_options,
        )

    async def create_organization(
        self,
        *,
        name: str,
        allow_profiles_outside_organization: Optional[bool] = None,
        domains: Optional[List[str]] = None,
        domain_data: Optional[List[OrganizationDomainData]] = None,
        metadata: Union[Dict[str, str], None, NotGiven] = NOT_GIVEN,
        external_id: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Create an Organization

        Creates a new organization in the current environment.

        Args:
            name: The name of the organization.
            allow_profiles_outside_organization: Whether the organization allows profiles from outside the organization to sign in.
            domains: The domains associated with the organization. Deprecated in favor of `domain_data`.
            domain_data: The domains associated with the organization, including verification state.
            metadata: Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization.
            external_id: An external identifier for the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            BadRequestError: If the request is malformed (400).
            ConflictError: If a conflict occurs (409).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
                "allow_profiles_outside_organization": allow_profiles_outside_organization,
                "domains": domains,
                "domain_data": [item.to_dict() for item in domain_data]
                if domain_data is not None
                else None,
            }.items()
            if v is not None
        }
        if not isinstance(metadata, NotGiven):
            body["metadata"] = metadata
        if not isinstance(external_id, NotGiven):
            body["external_id"] = external_id
        return await self._client.request(
            method="post",
            path=("organizations",),
            body=body,
            model=Organization,
            request_options=request_options,
        )

    async def get_organization_by_external_id(
        self,
        external_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Get an Organization by External ID

        Get the details of an existing organization by an [external identifier](https://workos.com/docs/authkit/metadata/external-identifiers).

        Args:
            external_id: The external ID of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return await self._client.request(
            method="get",
            path=("organizations", "external_id", str(external_id)),
            model=Organization,
            request_options=request_options,
        )

    async def get_organization(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Get an Organization

        Get the details of an existing organization.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return await self._client.request(
            method="get",
            path=("organizations", str(id)),
            model=Organization,
            request_options=request_options,
        )

    async def update_organization(
        self,
        id: str,
        *,
        name: Optional[str] = None,
        allow_profiles_outside_organization: Optional[bool] = None,
        domains: Optional[List[str]] = None,
        domain_data: Optional[List[OrganizationDomainData]] = None,
        stripe_customer_id: Optional[str] = None,
        metadata: Union[Dict[str, str], None, NotGiven] = NOT_GIVEN,
        external_id: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Organization:
        """Update an Organization

        Updates an organization in the current environment.

        Args:
            id: Unique identifier of the Organization.
            name: The name of the organization.
            allow_profiles_outside_organization: Whether the organization allows profiles from outside the organization to sign in.
            domains: (deprecated) The domains associated with the organization. Deprecated in favor of `domain_data`.
            domain_data: The domains associated with the organization, including verification state.
            stripe_customer_id: The Stripe customer ID associated with the organization.
            metadata: Object containing [metadata](https://workos.com/docs/authkit/metadata) key/value pairs associated with the Organization.
            external_id: An external identifier for the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Organization

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            ConflictError: If a conflict occurs (409).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
                "allow_profiles_outside_organization": allow_profiles_outside_organization,
                "domains": domains,
                "domain_data": [item.to_dict() for item in domain_data]
                if domain_data is not None
                else None,
                "stripe_customer_id": stripe_customer_id,
            }.items()
            if v is not None
        }
        if not isinstance(metadata, NotGiven):
            body["metadata"] = metadata
        if not isinstance(external_id, NotGiven):
            body["external_id"] = external_id
        return await self._client.request(
            method="put",
            path=("organizations", str(id)),
            body=body,
            model=Organization,
            request_options=request_options,
        )

    async def delete_organization(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Delete an Organization

        Permanently deletes an organization in the current environment. It cannot be undone.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        await self._client.request(
            method="delete",
            path=("organizations", str(id)),
            request_options=request_options,
        )

    async def get_audit_log_configuration(
        self,
        id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> AuditLogConfiguration:
        """Get Audit Log Configuration

        Get the unified view of audit log trail and stream configuration for an organization.

        Args:
            id: Unique identifier of the Organization.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AuditLogConfiguration

        Raises:
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return await self._client.request(
            method="get",
            path=("organizations", str(id), "audit_log_configuration"),
            model=AuditLogConfiguration,
            request_options=request_options,
        )

    async def list_authorized_applications(
        self,
        organization_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> AsyncPage[OrganizationAuthorizedConnectApplicationListData]:
        """List authorized applications

        Get a list of all Connect applications that users in the organization have authorized.

        Args:
            organization_id: The ID of the organization.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AsyncPage[OrganizationAuthorizedConnectApplicationListData]

        Raises:
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return await self._client.request_page(
            method="get",
            path=("organizations", str(organization_id), "authorized_applications"),
            model=OrganizationAuthorizedConnectApplicationListData,
            params=params,
            request_options=request_options,
        )
