# AUTO-GENERATED FILE - DO NOT EDIT
# This file was automatically generated by the XDK build tool.
# Any manual changes will be overwritten on the next generation.

"""
Auto-generated spaces client for the X API.

This module provides a client for interacting with the spaces endpoints of the X API.

All methods, parameters, and response models are generated from the OpenAPI specification.

Generated automatically - do not edit manually.
"""

from __future__ import annotations
from typing import Dict, List, Optional, Any, Union, cast, TYPE_CHECKING, Iterator
import requests
import time
import urllib.parse


if TYPE_CHECKING:
    from ..client import Client
from .models import (
    GetBuyersResponse,
    GetByIdsResponse,
    SearchResponse,
    GetByIdResponse,
    GetPostsResponse,
    GetByCreatorIdsResponse,
)


class SpacesClient:
    """Client for spaces operations"""


    def __init__(self, client: Client):
        self.client = client


    def get_buyers(
        self,
        id: str,
        pagination_token: Any = None,
        max_results: int = None,
        user_fields: List = None,
        expansions: List = None,
        tweet_fields: List = None,
    ) -> Iterator[GetBuyersResponse]:
        """
        Get Space ticket buyers
        Retrieves a list of Users who purchased tickets to a specific Space by its ID.
        Args:
            id: The ID of the Space to be retrieved.
            pagination_token: This parameter is used to get a specified 'page' of results.
            max_results: The maximum number of results.
            user_fields: A comma separated list of User fields to display.
            expansions: A comma separated list of fields to expand.
            tweet_fields: A comma separated list of Tweet fields to display.
            Yields:
            GetBuyersResponse: One page of results at a time. Automatically handles pagination using next_token.
        Note:
            This method automatically paginates through all results. To get just the first page,
            you can call it once and break, or use the pagination_token parameter to start at a specific page.
        """
        url = self.client.base_url + "/2/spaces/{id}/buyers"
        url = url.replace("{id}", str(id))
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        headers = {}
        # Prepare request data
        json_data = None
        # Determine pagination parameter name
        pagination_param_name = "pagination_token"
        # Start with provided pagination_token, or None for first page
        # Check if pagination_token parameter exists in the method signature
        current_pagination_token = pagination_token
        while True:
            # Build query parameters for this page
            page_params = {}
            if max_results is not None:
                page_params["max_results"] = max_results
            if user_fields is not None:
                page_params["user.fields"] = ",".join(str(item) for item in user_fields)
            if expansions is not None:
                page_params["expansions"] = ",".join(str(item) for item in expansions)
            if tweet_fields is not None:
                page_params["tweet.fields"] = ",".join(
                    str(item) for item in tweet_fields
                )
            # Add pagination token for this page
            if current_pagination_token:
                page_params[pagination_param_name] = current_pagination_token
            # Select authentication method (same logic as regular_request)
            # Priority strategy (matches TypeScript):
            # 1. If endpoint only accepts one method, use that (if available)
            # 2. If endpoint accepts multiple methods:
            #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
            #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
            # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
            page_selected_auth = None
            # Check what auth methods we have available
            page_available_bearer = bool(self.client.bearer_token)
            page_available_oauth2 = bool(self.client.access_token)
            page_available_oauth1 = bool(
                self.client.auth and self.client.auth.access_token
            )
            # Count acceptable schemes
            page_acceptable_schemes = []
            page_acceptable_schemes.append("OAuth2UserToken")
            # If only one scheme is acceptable, use it if available
            if len(page_acceptable_schemes) == 1:
                scheme = page_acceptable_schemes[0]
                if scheme == "BearerToken" and page_available_bearer:
                    page_selected_auth = "bearer_token"
                elif scheme == "OAuth2UserToken" and page_available_oauth2:
                    page_selected_auth = "oauth2_user_context"
                elif scheme == "UserToken" and page_available_oauth1:
                    page_selected_auth = "oauth1"
            # Multiple schemes acceptable - use priority based on operation type
            elif len(page_acceptable_schemes) > 1:
                is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
                if is_write_operation:
                    # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                    if "UserToken" in page_acceptable_schemes and page_available_oauth1:
                        page_selected_auth = "oauth1"
                    elif (
                        "OAuth2UserToken" in page_acceptable_schemes
                        and page_available_oauth2
                    ):
                        page_selected_auth = "oauth2_user_context"
                    elif (
                        "BearerToken" in page_acceptable_schemes
                        and page_available_bearer
                    ):
                        page_selected_auth = "bearer_token"
                else:
                    # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                    if (
                        "BearerToken" in page_acceptable_schemes
                        and page_available_bearer
                    ):
                        page_selected_auth = "bearer_token"
                    elif (
                        "OAuth2UserToken" in page_acceptable_schemes
                        and page_available_oauth2
                    ):
                        page_selected_auth = "oauth2_user_context"
                    elif (
                        "UserToken" in page_acceptable_schemes and page_available_oauth1
                    ):
                        page_selected_auth = "oauth1"
            # Apply selected authentication for this page
            page_headers = headers.copy()
            if page_selected_auth == "oauth1":
                # OAuth1 authentication - build proper OAuth1 header dynamically
                # Build OAuth1 header with method, URL, and body
                # For OAuth1, we need to include query params in the URL for signature
                full_url = url
                if page_params:
                    query_string = urllib.parse.urlencode(page_params)
                    full_url = f"{url}?{query_string}" if query_string else url
                # Prepare body for OAuth1 signature (form-encoded, not JSON)
                body_string = ""
                # Build OAuth1 authorization header
                oauth_header = self.client.auth.build_request_header(
                    method="get", url=full_url, body=body_string
                )
                page_headers["Authorization"] = oauth_header
            elif page_selected_auth == "bearer_token":
                # Bearer token authentication
                if self.client.bearer_token:
                    page_headers["Authorization"] = f"Bearer {self.client.bearer_token}"
                elif self.client.access_token:
                    page_headers["Authorization"] = f"Bearer {self.client.access_token}"
            elif page_selected_auth == "oauth2_user_context":
                # OAuth2 User Token authentication
                if self.client.access_token:
                    page_headers["Authorization"] = f"Bearer {self.client.access_token}"
                    # Check if token needs refresh
                    if self.client.oauth2_auth and self.client.token:
                        if self.client.is_token_expired():
                            self.client.refresh_token()
                            if self.client.access_token:
                                page_headers["Authorization"] = (
                                    f"Bearer {self.client.access_token}"
                                )
            # Make the request
            if not page_selected_auth:
                # No suitable auth method found - validate authentication
                required_schemes = (
                    page_acceptable_schemes
                    if "page_acceptable_schemes" in locals()
                    else []
                )
                if required_schemes:
                    available = []
                    if page_available_bearer and "BearerToken" in required_schemes:
                        available.append("BearerToken")
                    if page_available_oauth2 and "OAuth2UserToken" in required_schemes:
                        available.append("OAuth2UserToken")
                    if page_available_oauth1 and "UserToken" in required_schemes:
                        available.append("UserToken")
                    if not available:
                        raise ValueError(
                            f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and page_available_bearer) or (s == 'OAuth2UserToken' and page_available_oauth2) or (s == 'UserToken' and page_available_oauth1)]}"
                        )
            response = self.client.session.get(
                url,
                params=page_params,
                headers=page_headers,
            )
            # Check for errors
            response.raise_for_status()
            # Parse the response data
            response_data = response.json()
            # Convert to Pydantic model if applicable
            page_response = GetBuyersResponse.model_validate(response_data)
            # Yield this page
            yield page_response
            # Extract next_token from response
            next_token = None
            try:
                # Try response.meta.next_token (most common pattern)
                if hasattr(page_response, "meta") and page_response.meta is not None:
                    meta = page_response.meta
                    # If meta is a Pydantic model, try to dump it
                    if hasattr(meta, "model_dump"):
                        try:
                            meta_dict = meta.model_dump()
                            next_token = meta_dict.get("next_token")
                        except (AttributeError, TypeError):
                            pass
                    # Otherwise try attribute access
                    if not next_token and hasattr(meta, "next_token"):
                        next_token = getattr(meta, "next_token", None)
                    # If meta is a dict, access it directly
                    if not next_token and isinstance(meta, dict):
                        next_token = meta.get("next_token")
            except (AttributeError, TypeError):
                pass
            # Try dict access if we have a dict
            if not next_token and isinstance(response_data, dict):
                try:
                    meta = response_data.get("meta")
                    if meta and isinstance(meta, dict):
                        next_token = meta.get("next_token")
                except (AttributeError, TypeError, KeyError):
                    pass
            # If no next_token, we're done
            if not next_token:
                break
            # Update token for next iteration
            current_pagination_token = next_token

            # Optional: Add rate limit backoff here if needed
            # time.sleep(0.1)  # Small delay to avoid rate limits


    def get_by_ids(
        self,
        ids: List,
        space_fields: List = None,
        expansions: List = None,
        user_fields: List = None,
        topic_fields: List = None,
    ) -> GetByIdsResponse:
        """
        Get Spaces by IDs
        Retrieves details of multiple Spaces by their IDs.
        Args:
            ids: The list of Space IDs to return.
            space_fields: A comma separated list of Space fields to display.
            expansions: A comma separated list of fields to expand.
            user_fields: A comma separated list of User fields to display.
            topic_fields: A comma separated list of Topic fields to display.
            Returns:
            GetByIdsResponse: Response data
        """
        url = self.client.base_url + "/2/spaces"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        params = {}
        if ids is not None:
            params["ids"] = ",".join(str(item) for item in ids)
        if space_fields is not None:
            params["space.fields"] = ",".join(str(item) for item in space_fields)
        if expansions is not None:
            params["expansions"] = ",".join(str(item) for item in expansions)
        if user_fields is not None:
            params["user.fields"] = ",".join(str(item) for item in user_fields)
        if topic_fields is not None:
            params["topic.fields"] = ",".join(str(item) for item in topic_fields)
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        acceptable_schemes.append("OAuth2UserToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return GetByIdsResponse.model_validate(response_data)


    def search(
        self,
        query: str,
        state: str = None,
        max_results: int = None,
        space_fields: List = None,
        expansions: List = None,
        user_fields: List = None,
        topic_fields: List = None,
    ) -> SearchResponse:
        """
        Search Spaces
        Retrieves a list of Spaces matching the specified search query.
        Args:
            query: The search query.
            state: The state of Spaces to search for.
            max_results: The number of results to return.
            space_fields: A comma separated list of Space fields to display.
            expansions: A comma separated list of fields to expand.
            user_fields: A comma separated list of User fields to display.
            topic_fields: A comma separated list of Topic fields to display.
            Returns:
            SearchResponse: Response data
        """
        url = self.client.base_url + "/2/spaces/search"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        params = {}
        if query is not None:
            params["query"] = query
        if state is not None:
            params["state"] = state
        if max_results is not None:
            params["max_results"] = max_results
        if space_fields is not None:
            params["space.fields"] = ",".join(str(item) for item in space_fields)
        if expansions is not None:
            params["expansions"] = ",".join(str(item) for item in expansions)
        if user_fields is not None:
            params["user.fields"] = ",".join(str(item) for item in user_fields)
        if topic_fields is not None:
            params["topic.fields"] = ",".join(str(item) for item in topic_fields)
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        acceptable_schemes.append("OAuth2UserToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return SearchResponse.model_validate(response_data)


    def get_by_id(
        self,
        id: str,
        space_fields: List = None,
        expansions: List = None,
        user_fields: List = None,
        topic_fields: List = None,
    ) -> GetByIdResponse:
        """
        Get space by ID
        Retrieves details of a specific space by its ID.
        Args:
            id: The ID of the Space to be retrieved.
            space_fields: A comma separated list of Space fields to display.
            expansions: A comma separated list of fields to expand.
            user_fields: A comma separated list of User fields to display.
            topic_fields: A comma separated list of Topic fields to display.
            Returns:
            GetByIdResponse: Response data
        """
        url = self.client.base_url + "/2/spaces/{id}"
        url = url.replace("{id}", str(id))
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        params = {}
        if space_fields is not None:
            params["space.fields"] = ",".join(str(item) for item in space_fields)
        if expansions is not None:
            params["expansions"] = ",".join(str(item) for item in expansions)
        if user_fields is not None:
            params["user.fields"] = ",".join(str(item) for item in user_fields)
        if topic_fields is not None:
            params["topic.fields"] = ",".join(str(item) for item in topic_fields)
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        acceptable_schemes.append("OAuth2UserToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return GetByIdResponse.model_validate(response_data)


    def get_posts(
        self,
        id: str,
        max_results: int = None,
        tweet_fields: List = None,
        expansions: List = None,
        media_fields: List = None,
        poll_fields: List = None,
        user_fields: List = None,
        place_fields: List = None,
    ) -> GetPostsResponse:
        """
        Get Space Posts
        Retrieves a list of Posts shared in a specific Space by its ID.
        Args:
            id: The ID of the Space to be retrieved.
            max_results: The number of Posts to fetch from the provided space. If not provided, the value will default to the maximum of 100.
            tweet_fields: A comma separated list of Tweet fields to display.
            expansions: A comma separated list of fields to expand.
            media_fields: A comma separated list of Media fields to display.
            poll_fields: A comma separated list of Poll fields to display.
            user_fields: A comma separated list of User fields to display.
            place_fields: A comma separated list of Place fields to display.
            Returns:
            GetPostsResponse: Response data
        """
        url = self.client.base_url + "/2/spaces/{id}/tweets"
        url = url.replace("{id}", str(id))
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        params = {}
        if max_results is not None:
            params["max_results"] = max_results
        if tweet_fields is not None:
            params["tweet.fields"] = ",".join(str(item) for item in tweet_fields)
        if expansions is not None:
            params["expansions"] = ",".join(str(item) for item in expansions)
        if media_fields is not None:
            params["media.fields"] = ",".join(str(item) for item in media_fields)
        if poll_fields is not None:
            params["poll.fields"] = ",".join(str(item) for item in poll_fields)
        if user_fields is not None:
            params["user.fields"] = ",".join(str(item) for item in user_fields)
        if place_fields is not None:
            params["place.fields"] = ",".join(str(item) for item in place_fields)
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        acceptable_schemes.append("OAuth2UserToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return GetPostsResponse.model_validate(response_data)


    def get_by_creator_ids(
        self,
        user_ids: List,
        space_fields: List = None,
        expansions: List = None,
        user_fields: List = None,
        topic_fields: List = None,
    ) -> GetByCreatorIdsResponse:
        """
        Get Spaces by creator IDs
        Retrieves details of Spaces created by specified User IDs.
        Args:
            user_ids: The IDs of Users to search through.
            space_fields: A comma separated list of Space fields to display.
            expansions: A comma separated list of fields to expand.
            user_fields: A comma separated list of User fields to display.
            topic_fields: A comma separated list of Topic fields to display.
            Returns:
            GetByCreatorIdsResponse: Response data
        """
        url = self.client.base_url + "/2/spaces/by/creator_ids"
        # Priority: bearer_token > access_token (matches TypeScript behavior)
        if self.client.bearer_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.bearer_token}"
            )
        elif self.client.access_token:
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
        # OAuth2UserToken: Use access_token as bearer token (matches TypeScript behavior)
        # Priority: access_token > oauth2_session (for token refresh support)
        if self.client.access_token:
            # Use access_token directly as bearer token (matches TypeScript)
            self.client.session.headers["Authorization"] = (
                f"Bearer {self.client.access_token}"
            )
            # If we have oauth2_auth, check if token needs refresh
            if self.client.oauth2_auth and self.client.token:
                if self.client.is_token_expired():
                    self.client.refresh_token()
                    # Update access_token after refresh
                    if self.client.access_token:
                        self.client.session.headers["Authorization"] = (
                            f"Bearer {self.client.access_token}"
                        )
        elif self.client.oauth2_auth and self.client.token:
            # Fallback: use oauth2_session if available (for backward compatibility)
            # Check if token needs refresh
            if self.client.is_token_expired():
                self.client.refresh_token()
        params = {}
        if user_ids is not None:
            params["user_ids"] = ",".join(str(item) for item in user_ids)
        if space_fields is not None:
            params["space.fields"] = ",".join(str(item) for item in space_fields)
        if expansions is not None:
            params["expansions"] = ",".join(str(item) for item in expansions)
        if user_fields is not None:
            params["user.fields"] = ",".join(str(item) for item in user_fields)
        if topic_fields is not None:
            params["topic.fields"] = ",".join(str(item) for item in topic_fields)
        headers = {}
        # Prepare request data
        json_data = None
        # Select authentication method based on endpoint requirements and available credentials
        # Priority strategy (matches TypeScript):
        # 1. If endpoint only accepts one method, use that (if available)
        # 2. If endpoint accepts multiple methods:
        #    - For write operations (POST/PUT/DELETE/PATCH): Prefer OAuth1 > OAuth2 User Token > Bearer Token
        #    - For read operations (GET): Prefer Bearer Token > OAuth2 User Token > OAuth1
        # 3. If no security requirements: Bearer Token > OAuth2 User Token > OAuth1
        selected_auth = None
        # Check what auth methods we have available
        available_bearer = bool(self.client.bearer_token)
        available_oauth2 = bool(self.client.access_token)
        available_oauth1 = bool(self.client.auth and self.client.auth.access_token)
        # Count acceptable schemes
        acceptable_schemes = []
        acceptable_schemes.append("BearerToken")
        acceptable_schemes.append("OAuth2UserToken")
        # If only one scheme is acceptable, use it if available
        if len(acceptable_schemes) == 1:
            scheme = acceptable_schemes[0]
            if scheme == "BearerToken" and available_bearer:
                selected_auth = "bearer_token"
            elif scheme == "OAuth2UserToken" and available_oauth2:
                selected_auth = "oauth2_user_context"
            elif scheme == "UserToken" and available_oauth1:
                selected_auth = "oauth1"
        # Multiple schemes acceptable - use priority based on operation type
        elif len(acceptable_schemes) > 1:
            is_write_operation = "get" in ["POST", "PUT", "DELETE", "PATCH"]
            if is_write_operation:
                # Priority for write operations: OAuth1 > OAuth2 User Token > Bearer Token
                if "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
            else:
                # Priority for read operations: Bearer Token > OAuth2 User Token > OAuth1
                if "BearerToken" in acceptable_schemes and available_bearer:
                    selected_auth = "bearer_token"
                elif "OAuth2UserToken" in acceptable_schemes and available_oauth2:
                    selected_auth = "oauth2_user_context"
                elif "UserToken" in acceptable_schemes and available_oauth1:
                    selected_auth = "oauth1"
        # Apply selected authentication
        if selected_auth == "oauth1":
            # OAuth1 authentication - build proper OAuth1 header dynamically
            # Build OAuth1 header with method, URL, and body
            # For OAuth1, we need to include query params in the URL for signature
            full_url = url
            if params:
                query_string = urllib.parse.urlencode(params)
                full_url = f"{url}?{query_string}" if query_string else url
            # Prepare body for OAuth1 signature (form-encoded, not JSON)
            body_string = ""
            # Build OAuth1 authorization header
            oauth_header = self.client.auth.build_request_header(
                method="get", url=full_url, body=body_string
            )
            headers["Authorization"] = oauth_header
        elif selected_auth == "bearer_token":
            # Bearer token authentication
            if self.client.bearer_token:
                headers["Authorization"] = f"Bearer {self.client.bearer_token}"
            elif self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
        elif selected_auth == "oauth2_user_context":
            # OAuth2 User Token authentication
            if self.client.access_token:
                headers["Authorization"] = f"Bearer {self.client.access_token}"
                # Check if token needs refresh
                if self.client.oauth2_auth and self.client.token:
                    if self.client.is_token_expired():
                        self.client.refresh_token()
                        if self.client.access_token:
                            headers["Authorization"] = (
                                f"Bearer {self.client.access_token}"
                            )
        # Make the request
        if not selected_auth:
            # No suitable auth method found - validate authentication
            required_schemes = (
                acceptable_schemes if "acceptable_schemes" in locals() else []
            )
            if required_schemes:
                available = []
                if available_bearer and "BearerToken" in required_schemes:
                    available.append("BearerToken")
                if available_oauth2 and "OAuth2UserToken" in required_schemes:
                    available.append("OAuth2UserToken")
                if available_oauth1 and "UserToken" in required_schemes:
                    available.append("UserToken")
                if not available:
                    raise ValueError(
                        f"Authentication required for this endpoint. Required schemes: {required_schemes}. Available: {[s for s in required_schemes if (s == 'BearerToken' and available_bearer) or (s == 'OAuth2UserToken' and available_oauth2) or (s == 'UserToken' and available_oauth1)]}"
                    )
        response = self.client.session.get(
            url,
            params=params,
            headers=headers,
        )
        # Check for errors
        response.raise_for_status()
        # Parse the response data
        response_data = response.json()
        # Convert to Pydantic model if applicable
        return GetByCreatorIdsResponse.model_validate(response_data)
