from typing import Dict, Any, Optional, List, Callable, Union

class ChatResource:
    def __init__(self, client):
        self.client = client

    def send_message(
        self, 
        project_id: str, 
        message: str, 
        session_id: Optional[str] = None,
        page_url: Optional[str] = None,
        page_title: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """
        Send a message to a project's AI engine (Headless mode).
        
        Args:
            project_id: The Voni Project ID
            message: The user's message
            session_id: Optional session identifier for conversation continuity
            page_url: Optional URL of the page where the message is sent
            page_title: Optional title of the page
            metadata: Optional additional context for the AI
            
        Returns:
            The AI response and session details
        """
        data = {
            "message": message,
            "session_id": session_id,
            "page_url": page_url,
            "page_title": page_title,
            "metadata": metadata or {}
        }
        return self.client._request("POST", f"/widget/{project_id}/chat", json_data=data)

    def orchestrate(
        self, 
        project_id: str, 
        message: str, 
        handlers: Dict[str, Any],
        interceptors: Optional[List[Callable[[Dict[str, Any]], Union[Dict[str, Any], bool]]]] = None,
        session_id: Optional[str] = None,
        page_url: Optional[str] = None,
        page_title: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """
        Send a message and automatically execute actions via provided handler functions.
        
        Args:
            project_id: The Voni Project ID
            message: The user's message
            handlers: A dictionary mapping action names (click, fill, etc.) to functions
            interceptors: Optional list of functions to intercept/modify actions before handling
            session_id: Optional session identifier
            page_url: Optional page URL
            page_title: Optional page title
            metadata: Optional metadata
        """
        response = self.send_message(
            project_id=project_id,
            message=message,
            session_id=session_id,
            page_url=page_url,
            page_title=page_title,
            metadata=metadata
        )
        
        actions = response.get("actions", [])
        for action in actions:
            # Run interceptors
            cancelled = False
            if interceptors:
                for interceptor in interceptors:
                    result = interceptor(action)
                    if result is False:
                        cancelled = True
                        break
                    if isinstance(result, dict):
                        action = result
            
            if cancelled:
                continue

            action_type = action.get("action")
            tool_name = action.get("name")
            
            # Try specific handler (name or action type)
            handler = handlers.get(tool_name) or handlers.get(action_type)
            if handler:
                handler(action)
                
        return response
