from typing import Dict, Any, List, Optional
from ..utils import filter_none

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

    def list(self, project_id: str) -> Dict[str, Any]:
        """List all workflows for a project."""
        return self.client._request("GET", "/workflows", params={"project_id": project_id})

    def get(self, workflow_id: str) -> Dict[str, Any]:
        """Get a workflow by ID."""
        return self.client._request("GET", f"/workflows/{workflow_id}")

    def create(self, project_id: str, name: str, steps: List[Dict[str, Any]], 
               description: Optional[str] = None, triggers: Optional[List[Dict[str, Any]]] = None,
               is_active: Optional[bool] = None) -> Dict[str, Any]:
        """Create a new workflow."""
        data = filter_none({
            "name": name,
            "description": description,
            "triggers": triggers,
            "steps": steps,
            "is_active": is_active
        })
        return self.client._request("POST", "/workflows", params={"project_id": project_id}, json_data=data)

    def update(self, workflow_id: str, name: Optional[str] = None, 
               description: Optional[str] = None, triggers: Optional[List[Dict[str, Any]]] = None,
               steps: Optional[List[Dict[str, Any]]] = None, is_active: Optional[bool] = None) -> Dict[str, Any]:
        """Update a workflow."""
        data = filter_none({
            "name": name,
            "description": description,
            "triggers": triggers,
            "steps": steps,
            "is_active": is_active
        })
        return self.client._request("PATCH", f"/workflows/{workflow_id}", json_data=data)

    def delete(self, workflow_id: str) -> None:
        """Delete a workflow."""
        self.client._request("DELETE", f"/workflows/{workflow_id}")

    def trigger(self, workflow_id: str, input_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
        """Trigger a workflow execution."""
        data = {"input": input_data} if input_data else {}
        return self.client._request("POST", f"/workflows/{workflow_id}/trigger", json_data=data)

    def list_runs(self, workflow_id: str, limit: int = 20, offset: int = 0) -> Dict[str, Any]:
        """List workflow runs."""
        return self.client._request("GET", f"/workflows/{workflow_id}/runs", params={"limit": limit, "offset": offset})

    def get_run(self, run_id: str) -> Dict[str, Any]:
        """Get a workflow run by ID."""
        return self.client._request("GET", f"/workflows/runs/{run_id}")

    @staticmethod
    def create_llm_step(id: str, messages: Optional[List[Dict[str, str]]] = None, prompt: Optional[str] = None, 
                        model: str = "gpt-4", temperature: float = 0.7) -> Dict[str, Any]:
        """Create an LLM chat step configuration."""
        config = {"model": model, "temperature": temperature}
        if messages:
            config["messages"] = messages
        if prompt:
            config["prompt"] = prompt
        return {"id": id, "type": "llm_chat", "config": config}

    @staticmethod
    def create_crawl_step(id: str, url: str, limit: int = 1, depth: int = 1) -> Dict[str, Any]:
        """Create a web crawl step configuration."""
        return {"id": id, "type": "web_crawl", "config": {"url": url, "limit": limit, "depth": depth}}

    @staticmethod
    def create_http_step(id: str, url: str, method: str = "GET", headers: Optional[Dict[str, str]] = None, 
                         body: Any = None) -> Dict[str, Any]:
        """Create an HTTP request step configuration."""
        return {"id": id, "type": "http_request", "config": {"url": url, "method": method, "headers": headers, "body": body}}

    @staticmethod
    def create_delay_step(id: str, duration_ms: int) -> Dict[str, Any]:
        """Create a delay step configuration."""
        return {"id": id, "type": "delay", "config": {"duration": duration_ms}}

    @staticmethod
    def create_condition_step(id: str, left: Any, operator: str, right: Any, 
                              if_true: Optional[str] = None, if_false: Optional[str] = None) -> Dict[str, Any]:
        """Create a condition step configuration."""
        config = {"left": left, "operator": operator, "right": right}
        if if_true:
            config["if_true"] = if_true
        if if_false:
            config["if_false"] = if_false
        return {"id": id, "type": "condition", "config": config}

    @staticmethod
    def create_intent_step(id: str, input_text: str, categories: Dict[str, str], 
                           routes: Dict[str, str], model: Optional[str] = None) -> Dict[str, Any]:
        """Create an intent classification step configuration."""
        config = {
            "input": input_text,
            "categories": categories,
            "routes": routes
        }
        if model:
            config["model"] = model
        return {"id": id, "type": "intent_classification", "config": config}

    @staticmethod
    def create_client_action_step(id: str, action: str, **kwargs) -> Dict[str, Any]:
        """
        Create a client-side browser action step configuration.
        Use this to instruct the user's browser to perform an action.
        
        Args:
            id: Step ID
            action: Action type (e.g., 'navigate', 'click', 'fill', 'scroll', 'open_modal', 'verify_url')
            **kwargs: Additional parameters for the action (e.g., selector, value, description, params={...})
        """
        config = {
            "action": action,
            **kwargs
        }
        return {"id": id, "type": "client_action", "config": filter_none(config)}

    @staticmethod
    def create_verification_step(id: str, type: str, value: str = None, selector: str = None) -> Dict[str, Any]:
        """
        Create a verification step to assert the state of the page.
        This runs in the browser and will stop execution if the check fails.
        
        Args:
            id: Step ID
            type: Verification type ('url', 'text', 'element')
            value: Expected value (substring for URL/text)
            selector: CSS selector (required for 'text' and 'element')
        """
        action_map = {
            "url": "verify_url",
            "text": "verify_text",
            "element": "verify_element"
        }
        if type not in action_map:
            raise ValueError(f"Unknown verification type: {type}. Use 'url', 'text', or 'element'.")
            
        return WorkflowResource.create_client_action_step(
            id=id,
            action=action_map[type],
            value=value,
            selector=selector,
            reason=f"Verifying {type}"
        )

    @staticmethod
    def create_browser_step(id: str, action: str, selector: Optional[str] = None, 
                            value: Optional[str] = None, script: Optional[str] = None,
                            url: Optional[str] = None, **kwargs) -> Dict[str, Any]:
        """
        Create a browser interaction step configuration.
        action: 'navigate', 'click', 'type', 'wait', 'screenshot', 'evaluate', 'get_content',
                'hover', 'press', 'select_option', 'check', 'uncheck', 'drag_and_drop'
        """
        config = {
            "action": action, 
            "selector": selector, 
            "value": value, 
            "script": script,
            "url": url,
            **kwargs
        }
        return {"id": id, "type": "browser_interaction", "config": filter_none(config)}
        
    @staticmethod
    def create_browser_navigate_step(id: str, url: str) -> Dict[str, Any]:
        """Helper to create a browser navigation step."""
        return WorkflowResource.create_browser_step(id, "navigate", url=url)

    @staticmethod
    def create_browser_click_step(id: str, selector: str) -> Dict[str, Any]:
        """Helper to create a browser click step."""
        return WorkflowResource.create_browser_step(id, "click", selector=selector)

    @staticmethod
    def create_browser_type_step(id: str, selector: str, text: str) -> Dict[str, Any]:
        """Helper to create a browser type step."""
        return WorkflowResource.create_browser_step(id, "type", selector=selector, value=text)
        
    @staticmethod
    def create_browser_screenshot_step(id: str, full_page: bool = False) -> Dict[str, Any]:
        """Helper to create a browser screenshot step."""
        return WorkflowResource.create_browser_step(id, "screenshot", full_page=full_page)
        
    @staticmethod
    def create_browser_evaluate_step(id: str, script: str) -> Dict[str, Any]:
        """Helper to create a browser evaluate step."""
        return WorkflowResource.create_browser_step(id, "evaluate", script=script)

    @staticmethod
    def create_browser_wait_step(id: str, selector: Optional[str] = None, duration: Optional[int] = None) -> Dict[str, Any]:
        """Helper to create a browser wait step."""
        return WorkflowResource.create_browser_step(id, "wait", selector=selector, duration=duration)
