"""
Mailchimp connector.
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
try:
    from typing import Literal
except ImportError:
    from typing_extensions import Literal

from .connector_model import MailchimpConnectorModel
from ._vendored.connector_sdk.introspection import describe_entities, generate_tool_description
from .types import (
    AutomationsListParams,
    CampaignsGetParams,
    CampaignsListParams,
    EmailActivityListParams,
    InterestCategoriesGetParams,
    InterestCategoriesListParams,
    InterestsGetParams,
    InterestsListParams,
    ListMembersGetParams,
    ListMembersListParams,
    ListsGetParams,
    ListsListParams,
    ReportsGetParams,
    ReportsListParams,
    SegmentMembersListParams,
    SegmentsGetParams,
    SegmentsListParams,
    TagsListParams,
    UnsubscribesListParams,
)
if TYPE_CHECKING:
    from .models import MailchimpAuthConfig
# Import response models and envelope models at runtime
from .models import (
    MailchimpExecuteResult,
    MailchimpExecuteResultWithMeta,
    CampaignsListResult,
    ListsListResult,
    ListMembersListResult,
    ReportsListResult,
    EmailActivityListResult,
    AutomationsListResult,
    TagsListResult,
    InterestCategoriesListResult,
    InterestsListResult,
    SegmentsListResult,
    SegmentMembersListResult,
    UnsubscribesListResult,
    Automation,
    Campaign,
    EmailActivity,
    Interest,
    InterestCategory,
    List,
    ListMember,
    Report,
    Segment,
    SegmentMember,
    Tag,
    Unsubscribe,
)

# TypeVar for decorator type preservation
_F = TypeVar("_F", bound=Callable[..., Any])



class MailchimpConnector:
    """
    Type-safe Mailchimp API connector.

    Auto-generated from OpenAPI specification with full type safety.
    """

    connector_name = "mailchimp"
    connector_version = "1.0.1"
    vendored_sdk_version = "0.1.0"  # Version of vendored connector-sdk

    # Map of (entity, action) -> needs_envelope for envelope wrapping decision
    _ENVELOPE_MAP = {
        ("campaigns", "list"): True,
        ("campaigns", "get"): None,
        ("lists", "list"): True,
        ("lists", "get"): None,
        ("list_members", "list"): True,
        ("list_members", "get"): None,
        ("reports", "list"): True,
        ("reports", "get"): None,
        ("email_activity", "list"): True,
        ("automations", "list"): True,
        ("tags", "list"): True,
        ("interest_categories", "list"): True,
        ("interest_categories", "get"): None,
        ("interests", "list"): True,
        ("interests", "get"): None,
        ("segments", "list"): True,
        ("segments", "get"): None,
        ("segment_members", "list"): True,
        ("unsubscribes", "list"): True,
    }

    # Map of (entity, action) -> {python_param_name: api_param_name}
    # Used to convert snake_case TypedDict keys to API parameter names in execute()
    _PARAM_MAP = {
        ('campaigns', 'list'): {'count': 'count', 'offset': 'offset', 'type': 'type', 'status': 'status', 'before_send_time': 'before_send_time', 'since_send_time': 'since_send_time', 'before_create_time': 'before_create_time', 'since_create_time': 'since_create_time', 'list_id': 'list_id', 'folder_id': 'folder_id', 'sort_field': 'sort_field', 'sort_dir': 'sort_dir'},
        ('campaigns', 'get'): {'campaign_id': 'campaign_id'},
        ('lists', 'list'): {'count': 'count', 'offset': 'offset', 'before_date_created': 'before_date_created', 'since_date_created': 'since_date_created', 'before_campaign_last_sent': 'before_campaign_last_sent', 'since_campaign_last_sent': 'since_campaign_last_sent', 'email': 'email', 'sort_field': 'sort_field', 'sort_dir': 'sort_dir'},
        ('lists', 'get'): {'list_id': 'list_id'},
        ('list_members', 'list'): {'list_id': 'list_id', 'count': 'count', 'offset': 'offset', 'email_type': 'email_type', 'status': 'status', 'since_timestamp_opt': 'since_timestamp_opt', 'before_timestamp_opt': 'before_timestamp_opt', 'since_last_changed': 'since_last_changed', 'before_last_changed': 'before_last_changed', 'unique_email_id': 'unique_email_id', 'vip_only': 'vip_only', 'interest_category_id': 'interest_category_id', 'interest_ids': 'interest_ids', 'interest_match': 'interest_match', 'sort_field': 'sort_field', 'sort_dir': 'sort_dir'},
        ('list_members', 'get'): {'list_id': 'list_id', 'subscriber_hash': 'subscriber_hash'},
        ('reports', 'list'): {'count': 'count', 'offset': 'offset', 'type': 'type', 'before_send_time': 'before_send_time', 'since_send_time': 'since_send_time'},
        ('reports', 'get'): {'campaign_id': 'campaign_id'},
        ('email_activity', 'list'): {'campaign_id': 'campaign_id', 'count': 'count', 'offset': 'offset', 'since': 'since'},
        ('automations', 'list'): {'count': 'count', 'offset': 'offset', 'before_create_time': 'before_create_time', 'since_create_time': 'since_create_time', 'before_start_time': 'before_start_time', 'since_start_time': 'since_start_time', 'status': 'status'},
        ('tags', 'list'): {'list_id': 'list_id', 'name': 'name'},
        ('interest_categories', 'list'): {'list_id': 'list_id', 'count': 'count', 'offset': 'offset'},
        ('interest_categories', 'get'): {'list_id': 'list_id', 'interest_category_id': 'interest_category_id'},
        ('interests', 'list'): {'list_id': 'list_id', 'interest_category_id': 'interest_category_id', 'count': 'count', 'offset': 'offset'},
        ('interests', 'get'): {'list_id': 'list_id', 'interest_category_id': 'interest_category_id', 'interest_id': 'interest_id'},
        ('segments', 'list'): {'list_id': 'list_id', 'count': 'count', 'offset': 'offset', 'type': 'type', 'since_created_at': 'since_created_at', 'before_created_at': 'before_created_at', 'since_updated_at': 'since_updated_at', 'before_updated_at': 'before_updated_at'},
        ('segments', 'get'): {'list_id': 'list_id', 'segment_id': 'segment_id'},
        ('segment_members', 'list'): {'list_id': 'list_id', 'segment_id': 'segment_id', 'count': 'count', 'offset': 'offset'},
        ('unsubscribes', 'list'): {'campaign_id': 'campaign_id', 'count': 'count', 'offset': 'offset'},
    }

    def __init__(
        self,
        auth_config: MailchimpAuthConfig | None = None,
        external_user_id: str | None = None,
        airbyte_client_id: str | None = None,
        airbyte_client_secret: str | None = None,
        on_token_refresh: Any | None = None,
        data_center: str | None = None    ):
        """
        Initialize a new mailchimp connector instance.

        Supports both local and hosted execution modes:
        - Local mode: Provide `auth_config` for direct API calls
        - Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution

        Args:
            auth_config: Typed authentication configuration (required for local mode)
            external_user_id: External user ID (required for hosted mode)
            airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
            airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
            on_token_refresh: Optional callback for OAuth2 token refresh persistence.
                Called with new_tokens dict when tokens are refreshed. Can be sync or async.
                Example: lambda tokens: save_to_database(tokens)            data_center: The data center for your Mailchimp account (e.g., us1, us2, us6)
        Examples:
            # Local mode (direct API calls)
            connector = MailchimpConnector(auth_config=MailchimpAuthConfig(api_key="...", data_center="..."))
            # Hosted mode (executed on Airbyte cloud)
            connector = MailchimpConnector(
                external_user_id="user-123",
                airbyte_client_id="client_abc123",
                airbyte_client_secret="secret_xyz789"
            )

            # Local mode with OAuth2 token refresh callback
            def save_tokens(new_tokens: dict) -> None:
                # Persist updated tokens to your storage (file, database, etc.)
                with open("tokens.json", "w") as f:
                    json.dump(new_tokens, f)

            connector = MailchimpConnector(
                auth_config=MailchimpAuthConfig(access_token="...", refresh_token="..."),
                on_token_refresh=save_tokens
            )
        """
        # Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
        if external_user_id and airbyte_client_id and airbyte_client_secret:
            from ._vendored.connector_sdk.executor import HostedExecutor
            self._executor = HostedExecutor(
                external_user_id=external_user_id,
                airbyte_client_id=airbyte_client_id,
                airbyte_client_secret=airbyte_client_secret,
                connector_definition_id=str(MailchimpConnectorModel.id),
            )
        else:
            # Local mode: auth_config required
            if not auth_config:
                raise ValueError(
                    "Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
                    "or auth_config for local mode"
                )

            from ._vendored.connector_sdk.executor import LocalExecutor

            # Build config_values dict from server variables
            config_values: dict[str, str] = {}
            if data_center:
                config_values["data_center"] = data_center

            self._executor = LocalExecutor(
                model=MailchimpConnectorModel,
                auth_config=auth_config.model_dump() if auth_config else None,
                config_values=config_values,
                on_token_refresh=on_token_refresh
            )

            # Update base_url with server variables if provided
            base_url = self._executor.http_client.base_url
            if data_center:
                base_url = base_url.replace("{data_center}", data_center)
            self._executor.http_client.base_url = base_url

        # Initialize entity query objects
        self.campaigns = CampaignsQuery(self)
        self.lists = ListsQuery(self)
        self.list_members = ListMembersQuery(self)
        self.reports = ReportsQuery(self)
        self.email_activity = EmailActivityQuery(self)
        self.automations = AutomationsQuery(self)
        self.tags = TagsQuery(self)
        self.interest_categories = InterestCategoriesQuery(self)
        self.interests = InterestsQuery(self)
        self.segments = SegmentsQuery(self)
        self.segment_members = SegmentMembersQuery(self)
        self.unsubscribes = UnsubscribesQuery(self)

    # ===== TYPED EXECUTE METHOD (Recommended Interface) =====

    @overload
    async def execute(
        self,
        entity: Literal["campaigns"],
        action: Literal["list"],
        params: "CampaignsListParams"
    ) -> "CampaignsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["campaigns"],
        action: Literal["get"],
        params: "CampaignsGetParams"
    ) -> "Campaign": ...

    @overload
    async def execute(
        self,
        entity: Literal["lists"],
        action: Literal["list"],
        params: "ListsListParams"
    ) -> "ListsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["lists"],
        action: Literal["get"],
        params: "ListsGetParams"
    ) -> "List": ...

    @overload
    async def execute(
        self,
        entity: Literal["list_members"],
        action: Literal["list"],
        params: "ListMembersListParams"
    ) -> "ListMembersListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["list_members"],
        action: Literal["get"],
        params: "ListMembersGetParams"
    ) -> "ListMember": ...

    @overload
    async def execute(
        self,
        entity: Literal["reports"],
        action: Literal["list"],
        params: "ReportsListParams"
    ) -> "ReportsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["reports"],
        action: Literal["get"],
        params: "ReportsGetParams"
    ) -> "Report": ...

    @overload
    async def execute(
        self,
        entity: Literal["email_activity"],
        action: Literal["list"],
        params: "EmailActivityListParams"
    ) -> "EmailActivityListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["automations"],
        action: Literal["list"],
        params: "AutomationsListParams"
    ) -> "AutomationsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["tags"],
        action: Literal["list"],
        params: "TagsListParams"
    ) -> "TagsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["interest_categories"],
        action: Literal["list"],
        params: "InterestCategoriesListParams"
    ) -> "InterestCategoriesListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["interest_categories"],
        action: Literal["get"],
        params: "InterestCategoriesGetParams"
    ) -> "InterestCategory": ...

    @overload
    async def execute(
        self,
        entity: Literal["interests"],
        action: Literal["list"],
        params: "InterestsListParams"
    ) -> "InterestsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["interests"],
        action: Literal["get"],
        params: "InterestsGetParams"
    ) -> "Interest": ...

    @overload
    async def execute(
        self,
        entity: Literal["segments"],
        action: Literal["list"],
        params: "SegmentsListParams"
    ) -> "SegmentsListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["segments"],
        action: Literal["get"],
        params: "SegmentsGetParams"
    ) -> "Segment": ...

    @overload
    async def execute(
        self,
        entity: Literal["segment_members"],
        action: Literal["list"],
        params: "SegmentMembersListParams"
    ) -> "SegmentMembersListResult": ...

    @overload
    async def execute(
        self,
        entity: Literal["unsubscribes"],
        action: Literal["list"],
        params: "UnsubscribesListParams"
    ) -> "UnsubscribesListResult": ...


    @overload
    async def execute(
        self,
        entity: str,
        action: str,
        params: dict[str, Any]
    ) -> MailchimpExecuteResult[Any] | MailchimpExecuteResultWithMeta[Any, Any] | Any: ...

    async def execute(
        self,
        entity: str,
        action: str,
        params: dict[str, Any] | None = None
    ) -> Any:
        """
        Execute an entity operation with full type safety.

        This is the recommended interface for blessed connectors as it:
        - Uses the same signature as non-blessed connectors
        - Provides full IDE autocomplete for entity/action/params
        - Makes migration from generic to blessed connectors seamless

        Args:
            entity: Entity name (e.g., "customers")
            action: Operation action (e.g., "create", "get", "list")
            params: Operation parameters (typed based on entity+action)

        Returns:
            Typed response based on the operation

        Example:
            customer = await connector.execute(
                entity="customers",
                action="get",
                params={"id": "cus_123"}
            )
        """
        from ._vendored.connector_sdk.executor import ExecutionConfig

        # Remap parameter names from snake_case (TypedDict keys) to API parameter names
        if params:
            param_map = self._PARAM_MAP.get((entity, action), {})
            if param_map:
                params = {param_map.get(k, k): v for k, v in params.items()}

        # Use ExecutionConfig for both local and hosted executors
        config = ExecutionConfig(
            entity=entity,
            action=action,
            params=params
        )

        result = await self._executor.execute(config)

        if not result.success:
            raise RuntimeError(f"Execution failed: {result.error}")

        # Check if this operation has extractors configured
        has_extractors = self._ENVELOPE_MAP.get((entity, action), False)

        if has_extractors:
            # With extractors - return Pydantic envelope with data and meta
            if result.meta is not None:
                return MailchimpExecuteResultWithMeta[Any, Any](
                    data=result.data,
                    meta=result.meta
                )
            else:
                return MailchimpExecuteResult[Any](data=result.data)
        else:
            # No extractors - return raw response data
            return result.data

    # ===== INTROSPECTION METHODS =====

    @classmethod
    def describe(cls, func: _F) -> _F:
        """
        Decorator that populates a function's docstring with connector capabilities.

        This class method can be used as a decorator to automatically generate
        comprehensive documentation for AI tool functions.

        Usage:
            @mcp.tool()
            @MailchimpConnector.describe
            async def execute(entity: str, action: str, params: dict):
                '''Execute operations.'''
                ...

        The decorated function's __doc__ will be updated with:
        - Available entities and their actions
        - Parameter signatures with required (*) and optional (?) markers
        - Response structure documentation
        - Example questions (if available in OpenAPI spec)

        Args:
            func: The function to decorate

        Returns:
            The same function with updated __doc__
        """
        description = generate_tool_description(MailchimpConnectorModel)

        original_doc = func.__doc__ or ""
        if original_doc.strip():
            func.__doc__ = f"{original_doc.strip()}\n{description}"
        else:
            func.__doc__ = description

        return func

    def list_entities(self) -> list[dict[str, Any]]:
        """
        Get structured data about available entities, actions, and parameters.

        Returns a list of entity descriptions with:
        - entity_name: Name of the entity (e.g., "contacts", "deals")
        - description: Entity description from the first endpoint
        - available_actions: List of actions (e.g., ["list", "get", "create"])
        - parameters: Dict mapping action -> list of parameter dicts

        Example:
            entities = connector.list_entities()
            for entity in entities:
                print(f"{entity['entity_name']}: {entity['available_actions']}")
        """
        return describe_entities(MailchimpConnectorModel)

    def entity_schema(self, entity: str) -> dict[str, Any] | None:
        """
        Get the JSON schema for an entity.

        Args:
            entity: Entity name (e.g., "contacts", "companies")

        Returns:
            JSON schema dict describing the entity structure, or None if not found.

        Example:
            schema = connector.entity_schema("contacts")
            if schema:
                print(f"Contact properties: {list(schema.get('properties', {}).keys())}")
        """
        entity_def = next(
            (e for e in MailchimpConnectorModel.entities if e.name == entity),
            None
        )
        if entity_def is None:
            logging.getLogger(__name__).warning(
                f"Entity '{entity}' not found. Available entities: "
                f"{[e.name for e in MailchimpConnectorModel.entities]}"
            )
        return entity_def.entity_schema if entity_def else None



class CampaignsQuery:
    """
    Query class for Campaigns entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        count: int | None = None,
        offset: int | None = None,
        type: str | None = None,
        status: str | None = None,
        before_send_time: str | None = None,
        since_send_time: str | None = None,
        before_create_time: str | None = None,
        since_create_time: str | None = None,
        list_id: str | None = None,
        folder_id: str | None = None,
        sort_field: str | None = None,
        sort_dir: str | None = None,
        **kwargs
    ) -> CampaignsListResult:
        """
        Get all campaigns in an account

        Args:
            count: The number of records to return. Default is 10. Maximum is 1000.
            offset: Used for pagination, this is the number of records from a collection to skip.
            type: The campaign type
            status: The status of the campaign
            before_send_time: Restrict the response to campaigns sent before the set time
            since_send_time: Restrict the response to campaigns sent after the set time
            before_create_time: Restrict the response to campaigns created before the set time
            since_create_time: Restrict the response to campaigns created after the set time
            list_id: The unique id for the list
            folder_id: The unique folder id
            sort_field: Returns files sorted by the specified field
            sort_dir: Determines the order direction for sorted results
            **kwargs: Additional parameters

        Returns:
            CampaignsListResult
        """
        params = {k: v for k, v in {
            "count": count,
            "offset": offset,
            "type": type,
            "status": status,
            "before_send_time": before_send_time,
            "since_send_time": since_send_time,
            "before_create_time": before_create_time,
            "since_create_time": since_create_time,
            "list_id": list_id,
            "folder_id": folder_id,
            "sort_field": sort_field,
            "sort_dir": sort_dir,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("campaigns", "list", params)
        # Cast generic envelope to concrete typed result
        return CampaignsListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        campaign_id: str,
        **kwargs
    ) -> Campaign:
        """
        Get information about a specific campaign

        Args:
            campaign_id: The unique id for the campaign
            **kwargs: Additional parameters

        Returns:
            Campaign
        """
        params = {k: v for k, v in {
            "campaign_id": campaign_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("campaigns", "get", params)
        return result



class ListsQuery:
    """
    Query class for Lists entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        count: int | None = None,
        offset: int | None = None,
        before_date_created: str | None = None,
        since_date_created: str | None = None,
        before_campaign_last_sent: str | None = None,
        since_campaign_last_sent: str | None = None,
        email: str | None = None,
        sort_field: str | None = None,
        sort_dir: str | None = None,
        **kwargs
    ) -> ListsListResult:
        """
        Get information about all lists in the account

        Args:
            count: The number of records to return
            offset: Used for pagination
            before_date_created: Restrict response to lists created before the set date
            since_date_created: Restrict response to lists created after the set date
            before_campaign_last_sent: Restrict results to lists created before the last campaign send date
            since_campaign_last_sent: Restrict results to lists created after the last campaign send date
            email: Restrict results to lists that include a specific subscriber's email address
            sort_field: Returns files sorted by the specified field
            sort_dir: Determines the order direction for sorted results
            **kwargs: Additional parameters

        Returns:
            ListsListResult
        """
        params = {k: v for k, v in {
            "count": count,
            "offset": offset,
            "before_date_created": before_date_created,
            "since_date_created": since_date_created,
            "before_campaign_last_sent": before_campaign_last_sent,
            "since_campaign_last_sent": since_campaign_last_sent,
            "email": email,
            "sort_field": sort_field,
            "sort_dir": sort_dir,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("lists", "list", params)
        # Cast generic envelope to concrete typed result
        return ListsListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        list_id: str,
        **kwargs
    ) -> List:
        """
        Get information about a specific list in your Mailchimp account

        Args:
            list_id: The unique ID for the list
            **kwargs: Additional parameters

        Returns:
            List
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("lists", "get", params)
        return result



class ListMembersQuery:
    """
    Query class for ListMembers entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        count: int | None = None,
        offset: int | None = None,
        email_type: str | None = None,
        status: str | None = None,
        since_timestamp_opt: str | None = None,
        before_timestamp_opt: str | None = None,
        since_last_changed: str | None = None,
        before_last_changed: str | None = None,
        unique_email_id: str | None = None,
        vip_only: bool | None = None,
        interest_category_id: str | None = None,
        interest_ids: str | None = None,
        interest_match: str | None = None,
        sort_field: str | None = None,
        sort_dir: str | None = None,
        **kwargs
    ) -> ListMembersListResult:
        """
        Get information about members in a specific Mailchimp list

        Args:
            list_id: The unique ID for the list
            count: The number of records to return
            offset: Used for pagination
            email_type: The email type
            status: The subscriber's status
            since_timestamp_opt: Restrict results to subscribers who opted-in after the set timeframe
            before_timestamp_opt: Restrict results to subscribers who opted-in before the set timeframe
            since_last_changed: Restrict results to subscribers whose information changed after the set timeframe
            before_last_changed: Restrict results to subscribers whose information changed before the set timeframe
            unique_email_id: A unique identifier for the email address across all Mailchimp lists
            vip_only: A filter to return only the list's VIP members
            interest_category_id: The unique id for the interest category
            interest_ids: Used to filter list members by interests
            interest_match: Used to filter list members by interests
            sort_field: Returns files sorted by the specified field
            sort_dir: Determines the order direction for sorted results
            **kwargs: Additional parameters

        Returns:
            ListMembersListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "count": count,
            "offset": offset,
            "email_type": email_type,
            "status": status,
            "since_timestamp_opt": since_timestamp_opt,
            "before_timestamp_opt": before_timestamp_opt,
            "since_last_changed": since_last_changed,
            "before_last_changed": before_last_changed,
            "unique_email_id": unique_email_id,
            "vip_only": vip_only,
            "interest_category_id": interest_category_id,
            "interest_ids": interest_ids,
            "interest_match": interest_match,
            "sort_field": sort_field,
            "sort_dir": sort_dir,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("list_members", "list", params)
        # Cast generic envelope to concrete typed result
        return ListMembersListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        list_id: str,
        subscriber_hash: str,
        **kwargs
    ) -> ListMember:
        """
        Get information about a specific list member

        Args:
            list_id: The unique ID for the list
            subscriber_hash: The MD5 hash of the lowercase version of the list member's email address
            **kwargs: Additional parameters

        Returns:
            ListMember
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "subscriber_hash": subscriber_hash,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("list_members", "get", params)
        return result



class ReportsQuery:
    """
    Query class for Reports entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        count: int | None = None,
        offset: int | None = None,
        type: str | None = None,
        before_send_time: str | None = None,
        since_send_time: str | None = None,
        **kwargs
    ) -> ReportsListResult:
        """
        Get campaign reports

        Args:
            count: The number of records to return
            offset: Used for pagination
            type: The campaign type
            before_send_time: Restrict the response to campaigns sent before the set time
            since_send_time: Restrict the response to campaigns sent after the set time
            **kwargs: Additional parameters

        Returns:
            ReportsListResult
        """
        params = {k: v for k, v in {
            "count": count,
            "offset": offset,
            "type": type,
            "before_send_time": before_send_time,
            "since_send_time": since_send_time,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("reports", "list", params)
        # Cast generic envelope to concrete typed result
        return ReportsListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        campaign_id: str,
        **kwargs
    ) -> Report:
        """
        Get report details for a specific sent campaign

        Args:
            campaign_id: The unique id for the campaign
            **kwargs: Additional parameters

        Returns:
            Report
        """
        params = {k: v for k, v in {
            "campaign_id": campaign_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("reports", "get", params)
        return result



class EmailActivityQuery:
    """
    Query class for EmailActivity entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        campaign_id: str,
        count: int | None = None,
        offset: int | None = None,
        since: str | None = None,
        **kwargs
    ) -> EmailActivityListResult:
        """
        Get a list of member's subscriber activity in a specific campaign

        Args:
            campaign_id: The unique id for the campaign
            count: The number of records to return
            offset: Used for pagination
            since: Restrict results to email activity events that occur after a specific time
            **kwargs: Additional parameters

        Returns:
            EmailActivityListResult
        """
        params = {k: v for k, v in {
            "campaign_id": campaign_id,
            "count": count,
            "offset": offset,
            "since": since,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("email_activity", "list", params)
        # Cast generic envelope to concrete typed result
        return EmailActivityListResult(
            data=result.data,
            meta=result.meta
        )



class AutomationsQuery:
    """
    Query class for Automations entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        count: int | None = None,
        offset: int | None = None,
        before_create_time: str | None = None,
        since_create_time: str | None = None,
        before_start_time: str | None = None,
        since_start_time: str | None = None,
        status: str | None = None,
        **kwargs
    ) -> AutomationsListResult:
        """
        Get a summary of an account's classic automations

        Args:
            count: The number of records to return
            offset: Used for pagination
            before_create_time: Restrict the response to automations created before this time
            since_create_time: Restrict the response to automations created after this time
            before_start_time: Restrict the response to automations started before this time
            since_start_time: Restrict the response to automations started after this time
            status: Restrict the results to automations with the specified status
            **kwargs: Additional parameters

        Returns:
            AutomationsListResult
        """
        params = {k: v for k, v in {
            "count": count,
            "offset": offset,
            "before_create_time": before_create_time,
            "since_create_time": since_create_time,
            "before_start_time": before_start_time,
            "since_start_time": since_start_time,
            "status": status,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("automations", "list", params)
        # Cast generic envelope to concrete typed result
        return AutomationsListResult(
            data=result.data,
            meta=result.meta
        )



class TagsQuery:
    """
    Query class for Tags entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        name: str | None = None,
        **kwargs
    ) -> TagsListResult:
        """
        Search for tags on a list by name

        Args:
            list_id: The unique ID for the list
            name: The search query used to filter tags
            **kwargs: Additional parameters

        Returns:
            TagsListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "name": name,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("tags", "list", params)
        # Cast generic envelope to concrete typed result
        return TagsListResult(
            data=result.data,
            meta=result.meta
        )



class InterestCategoriesQuery:
    """
    Query class for InterestCategories entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        count: int | None = None,
        offset: int | None = None,
        **kwargs
    ) -> InterestCategoriesListResult:
        """
        Get information about a list's interest categories

        Args:
            list_id: The unique ID for the list
            count: The number of records to return
            offset: Used for pagination
            **kwargs: Additional parameters

        Returns:
            InterestCategoriesListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "count": count,
            "offset": offset,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("interest_categories", "list", params)
        # Cast generic envelope to concrete typed result
        return InterestCategoriesListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        list_id: str,
        interest_category_id: str,
        **kwargs
    ) -> InterestCategory:
        """
        Get information about a specific interest category

        Args:
            list_id: The unique ID for the list
            interest_category_id: The unique ID for the interest category
            **kwargs: Additional parameters

        Returns:
            InterestCategory
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "interest_category_id": interest_category_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("interest_categories", "get", params)
        return result



class InterestsQuery:
    """
    Query class for Interests entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        interest_category_id: str,
        count: int | None = None,
        offset: int | None = None,
        **kwargs
    ) -> InterestsListResult:
        """
        Get a list of this category's interests

        Args:
            list_id: The unique ID for the list
            interest_category_id: The unique ID for the interest category
            count: The number of records to return
            offset: Used for pagination
            **kwargs: Additional parameters

        Returns:
            InterestsListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "interest_category_id": interest_category_id,
            "count": count,
            "offset": offset,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("interests", "list", params)
        # Cast generic envelope to concrete typed result
        return InterestsListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        list_id: str,
        interest_category_id: str,
        interest_id: str,
        **kwargs
    ) -> Interest:
        """
        Get interests or group names for a specific category

        Args:
            list_id: The unique ID for the list
            interest_category_id: The unique ID for the interest category
            interest_id: The specific interest or group name
            **kwargs: Additional parameters

        Returns:
            Interest
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "interest_category_id": interest_category_id,
            "interest_id": interest_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("interests", "get", params)
        return result



class SegmentsQuery:
    """
    Query class for Segments entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        count: int | None = None,
        offset: int | None = None,
        type: str | None = None,
        since_created_at: str | None = None,
        before_created_at: str | None = None,
        since_updated_at: str | None = None,
        before_updated_at: str | None = None,
        **kwargs
    ) -> SegmentsListResult:
        """
        Get information about all available segments for a specific list

        Args:
            list_id: The unique ID for the list
            count: The number of records to return
            offset: Used for pagination
            type: Limit results based on segment type
            since_created_at: Restrict results to segments created after the set time
            before_created_at: Restrict results to segments created before the set time
            since_updated_at: Restrict results to segments updated after the set time
            before_updated_at: Restrict results to segments updated before the set time
            **kwargs: Additional parameters

        Returns:
            SegmentsListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "count": count,
            "offset": offset,
            "type": type,
            "since_created_at": since_created_at,
            "before_created_at": before_created_at,
            "since_updated_at": since_updated_at,
            "before_updated_at": before_updated_at,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("segments", "list", params)
        # Cast generic envelope to concrete typed result
        return SegmentsListResult(
            data=result.data,
            meta=result.meta
        )



    async def get(
        self,
        list_id: str,
        segment_id: str,
        **kwargs
    ) -> Segment:
        """
        Get information about a specific segment

        Args:
            list_id: The unique ID for the list
            segment_id: The unique id for the segment
            **kwargs: Additional parameters

        Returns:
            Segment
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "segment_id": segment_id,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("segments", "get", params)
        return result



class SegmentMembersQuery:
    """
    Query class for SegmentMembers entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        list_id: str,
        segment_id: str,
        count: int | None = None,
        offset: int | None = None,
        **kwargs
    ) -> SegmentMembersListResult:
        """
        Get information about members in a saved segment

        Args:
            list_id: The unique ID for the list
            segment_id: The unique id for the segment
            count: The number of records to return
            offset: Used for pagination
            **kwargs: Additional parameters

        Returns:
            SegmentMembersListResult
        """
        params = {k: v for k, v in {
            "list_id": list_id,
            "segment_id": segment_id,
            "count": count,
            "offset": offset,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("segment_members", "list", params)
        # Cast generic envelope to concrete typed result
        return SegmentMembersListResult(
            data=result.data,
            meta=result.meta
        )



class UnsubscribesQuery:
    """
    Query class for Unsubscribes entity operations.
    """

    def __init__(self, connector: MailchimpConnector):
        """Initialize query with connector reference."""
        self._connector = connector

    async def list(
        self,
        campaign_id: str,
        count: int | None = None,
        offset: int | None = None,
        **kwargs
    ) -> UnsubscribesListResult:
        """
        Get information about members who have unsubscribed from a specific campaign

        Args:
            campaign_id: The unique id for the campaign
            count: The number of records to return
            offset: Used for pagination
            **kwargs: Additional parameters

        Returns:
            UnsubscribesListResult
        """
        params = {k: v for k, v in {
            "campaign_id": campaign_id,
            "count": count,
            "offset": offset,
            **kwargs
        }.items() if v is not None}

        result = await self._connector.execute("unsubscribes", "list", params)
        # Cast generic envelope to concrete typed result
        return UnsubscribesListResult(
            data=result.data,
            meta=result.meta
        )


