"""
Thread resource for managing email threads and labels.
"""

from typing import Any, Dict, List, Optional

from emailr.http import AsyncHttpClient, HttpClient
from emailr.types import (
    Pagination,
    PaginatedResponse,
    Thread,
    ThreadDetail,
    UpdateLabelsRequest,
    UpdateLabelsResponse,
    UpdateThreadLabelsResponse,
)


class ThreadsResource:
    """Synchronous thread resource for managing email threads."""

    def __init__(self, http: HttpClient) -> None:
        self._http = http

    def list(
        self,
        *,
        label: Optional[str] = None,
        page: Optional[int] = None,
        limit: Optional[int] = None,
        search: Optional[str] = None,
        inbox_id: Optional[str] = None,
    ) -> PaginatedResponse[Thread]:
        """
        List email threads with optional filtering.

        Args:
            label: Filter by label (inbox, sent, starred, spam, trash, archived, all)
            page: Page number
            limit: Results per page
            search: Search query for subject/sender
            inbox_id: Filter by inbox ID

        Returns:
            Paginated list of threads
        """
        params: Dict[str, Any] = {}
        if label is not None:
            params["label"] = label
        if page is not None:
            params["page"] = str(page)
        if limit is not None:
            params["limit"] = str(limit)
        if search is not None:
            params["search"] = search
        if inbox_id is not None:
            params["inbox_id"] = inbox_id

        data = self._http.get("/v1/threads", params=params)
        return PaginatedResponse(
            data=[Thread.from_dict(t) for t in data.get("data", [])],
            pagination=Pagination(
                page=data["pagination"]["page"],
                limit=data["pagination"]["limit"],
                total=data["pagination"]["total"],
                pages=data["pagination"]["pages"],
            ),
        )

    def get(self, thread_id: str) -> ThreadDetail:
        """
        Get thread detail with all messages.

        Args:
            thread_id: Thread ID

        Returns:
            Thread detail with messages
        """
        data = self._http.get(f"/v1/threads/{thread_id}")
        return ThreadDetail.from_dict(data)

    def update_labels(
        self,
        thread_id: str,
        *,
        add: Optional[List[str]] = None,
        remove: Optional[List[str]] = None,
    ) -> UpdateThreadLabelsResponse:
        """
        Add or remove labels from all emails in a thread.

        Args:
            thread_id: Thread ID
            add: Labels to add
            remove: Labels to remove

        Returns:
            Update response with count of updated emails
        """
        request = UpdateLabelsRequest(add=add, remove=remove)
        data = self._http.patch(f"/v1/threads/{thread_id}/labels", request.to_dict())
        return UpdateThreadLabelsResponse.from_dict(data)

    def update_email_labels(
        self,
        email_id: str,
        *,
        add: Optional[List[str]] = None,
        remove: Optional[List[str]] = None,
    ) -> UpdateLabelsResponse:
        """
        Add or remove labels from a single email.

        Args:
            email_id: Email ID
            add: Labels to add
            remove: Labels to remove

        Returns:
            Update response with resulting labels
        """
        request = UpdateLabelsRequest(add=add, remove=remove)
        data = self._http.patch(f"/v1/threads/emails/{email_id}/labels", request.to_dict())
        return UpdateLabelsResponse.from_dict(data)


class AsyncThreadsResource:
    """Asynchronous thread resource for managing email threads."""

    def __init__(self, http: AsyncHttpClient) -> None:
        self._http = http

    async def list(
        self,
        *,
        label: Optional[str] = None,
        page: Optional[int] = None,
        limit: Optional[int] = None,
        search: Optional[str] = None,
        inbox_id: Optional[str] = None,
    ) -> PaginatedResponse[Thread]:
        """List email threads with optional filtering."""
        params: Dict[str, Any] = {}
        if label is not None:
            params["label"] = label
        if page is not None:
            params["page"] = str(page)
        if limit is not None:
            params["limit"] = str(limit)
        if search is not None:
            params["search"] = search
        if inbox_id is not None:
            params["inbox_id"] = inbox_id

        data = await self._http.get("/v1/threads", params=params)
        return PaginatedResponse(
            data=[Thread.from_dict(t) for t in data.get("data", [])],
            pagination=Pagination(
                page=data["pagination"]["page"],
                limit=data["pagination"]["limit"],
                total=data["pagination"]["total"],
                pages=data["pagination"]["pages"],
            ),
        )

    async def get(self, thread_id: str) -> ThreadDetail:
        """Get thread detail with all messages."""
        data = await self._http.get(f"/v1/threads/{thread_id}")
        return ThreadDetail.from_dict(data)

    async def update_labels(
        self,
        thread_id: str,
        *,
        add: Optional[List[str]] = None,
        remove: Optional[List[str]] = None,
    ) -> UpdateThreadLabelsResponse:
        """Add or remove labels from all emails in a thread."""
        request = UpdateLabelsRequest(add=add, remove=remove)
        data = await self._http.patch(f"/v1/threads/{thread_id}/labels", request.to_dict())
        return UpdateThreadLabelsResponse.from_dict(data)

    async def update_email_labels(
        self,
        email_id: str,
        *,
        add: Optional[List[str]] = None,
        remove: Optional[List[str]] = None,
    ) -> UpdateLabelsResponse:
        """Add or remove labels from a single email."""
        request = UpdateLabelsRequest(add=add, remove=remove)
        data = await self._http.patch(f"/v1/threads/emails/{email_id}/labels", request.to_dict())
        return UpdateLabelsResponse.from_dict(data)
