"""Subscriber management resource."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from resletter.types import (
    CreateBulkSubscribersResponse,
    CreateSubscriberResponse,
    ListSubscribersResponse,
    Subscriber,
)

if TYPE_CHECKING:
    from resletter.client import Resletter


class SubscribersResource:
    """Subscriber management resource.

    Example:
        >>> # List subscribers
        >>> response = client.subscribers.list(status="subscribed", limit=50)
        >>> for subscriber in response["subscribers"]:
        ...     print(subscriber["email"])

        >>> # Create a subscriber
        >>> subscriber = client.subscribers.create(
        ...     email="user@example.com",
        ...     name="John Doe",
        ...     metadata={"source": "website"},
        ... )
    """

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

    def list(
        self,
        *,
        page: int | None = None,
        limit: int | None = None,
        status: str | None = None,
        group_id: str | None = None,
        email: str | None = None,
    ) -> ListSubscribersResponse:
        """List subscribers with optional filtering and pagination.

        Args:
            page: Page number (1-indexed).
            limit: Number of results per page (max 100).
            status: Filter by status ('subscribed', 'pending', 'unsubscribed', 'bounced').
            group_id: Filter by group ID.
            email: Filter by email (partial match).

        Returns:
            Dictionary with 'subscribers' list and 'pagination' info.

        Example:
            >>> result = client.subscribers.list(page=1, limit=50, status="subscribed")
            >>> print(f"Found {result['pagination']['total']} subscribers")
        """
        params: dict[str, Any] = {}
        if page is not None:
            params["page"] = page
        if limit is not None:
            params["limit"] = limit
        if status is not None:
            params["status"] = status
        if group_id is not None:
            params["groupId"] = group_id
        if email is not None:
            params["email"] = email

        return self._client._request("GET", "/subscribers", params=params)

    def get(self, subscriber_id: str) -> Subscriber:
        """Get a subscriber by ID.

        Args:
            subscriber_id: The subscriber's unique ID.

        Returns:
            Subscriber data.

        Raises:
            ResletterError: If subscriber not found (404).
        """
        return self._client._request("GET", f"/subscribers/{subscriber_id}")

    def create(
        self,
        *,
        email: str,
        name: str | None = None,
        metadata: dict[str, Any] | None = None,
        group_ids: list[str] | None = None,
        bypass_double_opt_in: bool = False,
    ) -> CreateSubscriberResponse:
        """Create a new subscriber.

        Args:
            email: Subscriber's email address (required).
            name: Subscriber's name.
            metadata: Custom metadata dictionary.
            group_ids: List of group IDs to add the subscriber to.
            bypass_double_opt_in: If True, skip confirmation email.

        Returns:
            Created subscriber data with 'isNew' flag.

        Example:
            >>> subscriber = client.subscribers.create(
            ...     email="user@example.com",
            ...     name="John Doe",
            ...     metadata={"plan": "pro"},
            ...     group_ids=["group-uuid"],
            ...     bypass_double_opt_in=True,
            ... )
            >>> print(f"Created: {subscriber['id']}, New: {subscriber['isNew']}")
        """
        body: dict[str, Any] = {"email": email}
        if name is not None:
            body["name"] = name
        if metadata is not None:
            body["metadata"] = metadata
        if group_ids is not None:
            body["groupIds"] = group_ids
        if bypass_double_opt_in:
            body["bypassDoubleOptIn"] = True

        return self._client._request("POST", "/subscribers", json=body)

    def create_bulk(
        self,
        *,
        subscribers: list[dict[str, Any]],
        group_ids: list[str] | None = None,
        skip_duplicates: bool = False,
        bypass_double_opt_in: bool = False,
    ) -> CreateBulkSubscribersResponse:
        """Create multiple subscribers at once (max 1000).

        Args:
            subscribers: List of subscriber dicts with 'email', optional 'name' and 'metadata'.
            group_ids: List of group IDs to add all subscribers to.
            skip_duplicates: If True, skip existing emails without error.
            bypass_double_opt_in: If True, skip confirmation emails.

        Returns:
            Results with counts of created, skipped, pending, and any errors.

        Example:
            >>> result = client.subscribers.create_bulk(
            ...     subscribers=[
            ...         {"email": "user1@example.com", "name": "User 1"},
            ...         {"email": "user2@example.com", "name": "User 2"},
            ...     ],
            ...     group_ids=["group-uuid"],
            ...     skip_duplicates=True,
            ... )
            >>> print(f"Created: {result['results']['created']}")
        """
        body: dict[str, Any] = {"subscribers": subscribers}
        if group_ids is not None:
            body["groupIds"] = group_ids
        if skip_duplicates:
            body["skipDuplicates"] = True
        if bypass_double_opt_in:
            body["bypassDoubleOptIn"] = True

        return self._client._request("POST", "/subscribers/bulk", json=body)

    def update(
        self,
        subscriber_id: str,
        *,
        name: str | None = None,
        metadata: dict[str, Any] | None = None,
        group_ids: list[str] | None = None,
    ) -> Subscriber:
        """Update a subscriber.

        Args:
            subscriber_id: The subscriber's unique ID.
            name: New name.
            metadata: New metadata (replaces existing).
            group_ids: New group IDs (replaces existing group memberships).

        Returns:
            Updated subscriber data.
        """
        body: dict[str, Any] = {}
        if name is not None:
            body["name"] = name
        if metadata is not None:
            body["metadata"] = metadata
        if group_ids is not None:
            body["groupIds"] = group_ids

        return self._client._request("PATCH", f"/subscribers/{subscriber_id}", json=body)

    def delete(self, subscriber_id: str, *, hard: bool = False) -> dict[str, str]:
        """Delete or unsubscribe a subscriber.

        Args:
            subscriber_id: The subscriber's unique ID.
            hard: If True, permanently delete. If False (default), unsubscribe.

        Returns:
            Dictionary with 'message' key.

        Example:
            >>> # Soft delete (unsubscribe)
            >>> client.subscribers.delete("subscriber-id")

            >>> # Hard delete (permanent)
            >>> client.subscribers.delete("subscriber-id", hard=True)
        """
        params = {"hard": "true"} if hard else None
        return self._client._request("DELETE", f"/subscribers/{subscriber_id}", params=params)
