"""Conversation store client for fetching conversation history."""

import logging
from typing import List, Dict, Any, Optional
import aiohttp

from .exceptions import APIException

logger = logging.getLogger(__name__)


class ConversationClient:
    """Client for interacting with conversation-store API (async)."""

    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip("/")
        self._session: Optional[aiohttp.ClientSession] = None

    async def _get_session(self) -> aiohttp.ClientSession:
        """Get or create aiohttp session."""
        if self._session is None or self._session.closed:
            timeout = aiohttp.ClientTimeout(total=10.0)
            self._session = aiohttp.ClientSession(timeout=timeout)
        return self._session

    async def close(self):
        """Close the aiohttp session."""
        if self._session and not self._session.closed:
            await self._session.close()

    async def get_conversation(self, conversation_id: str) -> Dict[str, Any]:
        """Get conversation metadata."""
        url = f"{self.base_url}/conversations/{conversation_id}"
        session = await self._get_session()
        try:
            async with session.get(url) as response:
                if response.status == 404:
                    raise APIException(f"Conversation {conversation_id} not found")
                response.raise_for_status()
                return await response.json()
        except aiohttp.ClientError as e:
            raise APIException(f"Failed to fetch conversation: {e}")

    async def get_messages(
        self,
        conversation_id: str,
        role: Optional[str] = None,
        from_: Optional[str] = None,
        to_: Optional[str] = None,
        limit: int = 100,
        offset: int = 0,
    ) -> List[Dict[str, Any]]:
        """Get messages from a conversation."""
        url = f"{self.base_url}/conversations/{conversation_id}/messages"
        params = {"limit": min(limit, 1000), "offset": offset}
        if role:
            params["role"] = role
        if from_:
            params["from"] = from_
        if to_:
            params["to"] = to_

        session = await self._get_session()
        try:
            async with session.get(url, params=params) as response:
                if response.status == 404:
                    raise APIException(f"Conversation {conversation_id} not found")
                response.raise_for_status()
                return await response.json()
        except aiohttp.ClientError as e:
            raise APIException(f"Failed to fetch messages: {e}")

    async def update_conversation(
        self,
        conversation_id: str,
        data: Dict[str, Any],
    ) -> Dict[str, Any]:
        """Update conversation fields (PATCH)."""
        url = f"{self.base_url}/conversations/{conversation_id}"
        session = await self._get_session()
        try:
            async with session.patch(url, json=data) as response:
                response.raise_for_status()
                return await response.json()
        except aiohttp.ClientError as e:
            raise APIException(f"Failed to update conversation: {e}")

    async def create_message(
        self,
        conversation_id: str,
        role: str,
        content: str,
        from_: Optional[str] = None,
        to_: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """Create a message in a conversation."""
        url = f"{self.base_url}/conversations/{conversation_id}/messages"
        payload: Dict[str, Any] = {"role": role, "content": content}
        if from_:
            payload["from_"] = from_
        if to_:
            payload["to_"] = to_
        if metadata:
            payload["metadata_"] = metadata
        session = await self._get_session()
        try:
            async with session.post(url, json=payload) as response:
                response.raise_for_status()
                return await response.json()
        except aiohttp.ClientError as e:
            raise APIException(f"Failed to create message: {e}")

    async def create_conversation(
        self,
        user_id: str,
        title: Optional[str] = None,
        agent_identifier: Optional[str] = None,
        current_route: Optional[str] = None,
        locked_by: Optional[str] = None,
        is_new: bool = False,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """Create a new conversation.

        Args:
            user_id: User identifier (UUID string)
            title: Conversation title
            agent_identifier: Agent name that initiated the conversation
            current_route: Agent currently handling the conversation
            locked_by: Agent currently generating a response
            is_new: Whether this conversation was agent-initiated
            metadata: Additional conversation metadata

        Returns:
            Full conversation response dict (contains id, tenant_id, etc.)
        """
        url = f"{self.base_url}/conversations/"
        payload: Dict[str, Any] = {
            "tenant_name": "frontline",
            "user_id": user_id,
            "is_new": is_new,
        }

        if title is not None:
            payload["title"] = title
        if agent_identifier is not None:
            payload["agent_identifier"] = agent_identifier
        if current_route is not None:
            payload["current_route"] = current_route
        if locked_by is not None:
            payload["locked_by"] = locked_by
        if metadata is not None:
            payload["metadata"] = metadata

        session = await self._get_session()
        try:
            async with session.post(url, json=payload) as response:
                response.raise_for_status()
                return await response.json()
        except aiohttp.ClientError as e:
            raise APIException(f"Failed to create conversation: {e}")
