"""
Clean, unified workspace creation API.

This module provides a single function to create workspaces with all
configuration as optional parameters. No builders, no multiple steps.
"""

from typing import Optional, Callable, Any, Union
from synqed.workspace_engine import AgentInfo, WorkspaceConfig, WorkspaceEngine
from synqed.protocols import ProtocolType, ProtocolConfig
from synqed.scheduler import SchedulerConfig, SchedulingStrategy


def create_workspace(
    name: str,
    task: Optional[str] = None,
    agents: Optional[list[AgentInfo]] = None,
    context: Optional[dict[str, Any]] = None,
    # Protocol configuration
    protocol: Union[str, ProtocolType] = ProtocolType.CONSENSUS,
    max_rounds: int = 5,
    max_turns_per_agent_per_round: int = 1,
    convergence_threshold: float = 0.8,
    # Execution limits
    max_messages: int = 100,
    max_total_tokens: Optional[int] = None,
    timeout_seconds: int = 300,
    # Scheduling
    scheduling_strategy: SchedulingStrategy = SchedulingStrategy.PROTOCOL_DRIVEN,
    max_consecutive_turns: int = 1,  # Set to 1 to disallow, 2+ to allow consecutive turns
    # Display
    display_messages: bool = False,  # Enable built-in colored message display
    display_verbose: bool = False,   # Show full message details (type, phase, etc.)
    # Callbacks
    on_message: Optional[Callable] = None,
    on_phase_change: Optional[Callable] = None,
    on_round_end: Optional[Callable] = None,
    # Metadata
    description: str = "",
    workspace_id: Optional[str] = None,
    auto_start: bool = True,
    persist_state: bool = False,
) -> WorkspaceEngine:
    """
    Create a workspace with a single function call.
    
    This is the ONE function you need to create any workspace. All configuration
    is done through parameters with sensible defaults.
    
    Args:
        name: Workspace name
        task: The task for agents to accomplish (can be set later via initialize())
        agents: List of agents to add (can be added later via initialize())
        context: Additional context dictionary
        
        # Protocol Configuration
        protocol: Protocol type - "consensus", "debate", "critique", or ProtocolType enum
        max_rounds: Maximum number of rounds
        max_turns_per_agent_per_round: How many times each agent can speak per round
        convergence_threshold: For consensus protocol (0.0-1.0)
        
        # Execution Limits
        max_messages: Maximum total messages before termination
        max_total_tokens: Maximum tokens before termination (optional)
        timeout_seconds: Timeout in seconds
        
        # Scheduling
        scheduling_strategy: How to schedule agent turns
        max_consecutive_turns: Max consecutive turns for same agent (set to 1 to disallow)
        
        # Display
        display_messages: Enable built-in colored message display (default: False)
        display_verbose: Show full message details including type and phase (default: False)
        
        # Callbacks
        on_message: Called when a message is sent (can be combined with display_messages)
        on_phase_change: Called when protocol phase changes
        on_round_end: Called when a round completes
        
        # Metadata
        description: Workspace description
        workspace_id: Custom workspace ID (auto-generated if not provided)
        auto_start: Whether to auto-initialize when run() is called
        persist_state: Whether to persist workspace state
    
    Returns:
        WorkspaceEngine ready to run
    
    Examples:
        # Simple consensus workspace with real-time display
        workspace = create_workspace(
            name="Team Planning",
            task="Plan the project",
            agents=[agent1, agent2, agent3],
            display_messages=True,  # Enable colored message display
        )
        result = await workspace.run()
        
        # Debate workspace with custom settings
        workspace = create_workspace(
            name="Policy Debate",
            task="Should we adopt policy X?",
            agents=[advocate, critic],
            protocol="debate",
            max_rounds=3,
            timeout_seconds=600,
            display_messages=True,  # Built-in colored display
        )
        
        # Advanced configuration
        workspace = create_workspace(
            name="Research Team",
            task="Analyze the data",
            agents=[analyst, reviewer, synthesizer],
            protocol=ProtocolType.CRITIQUE_AND_REVISE,
            max_rounds=4,
            max_turns_per_agent_per_round=2,
            max_messages=200,
            max_total_tokens=50000,
            scheduling_strategy=SchedulingStrategy.ROUND_ROBIN,
            on_round_end=lambda round_num, stats: print(f"Round {round_num} done"),
        )
        
        # Create empty workspace and configure later
        workspace = create_workspace(name="Empty", auto_start=False)
        await workspace.initialize(task="My task", agents=[agent1, agent2])
        await workspace.run()
    """
    # Parse protocol
    if isinstance(protocol, str):
        protocol_map = {
            "consensus": ProtocolType.CONSENSUS,
            "debate": ProtocolType.DEBATE,
            "critique": ProtocolType.CRITIQUE_AND_REVISE,
            "critique_and_revise": ProtocolType.CRITIQUE_AND_REVISE,
        }
        protocol_type = protocol_map.get(protocol.lower(), ProtocolType.CONSENSUS)
    else:
        protocol_type = protocol
    
    # Build protocol config
    protocol_config = ProtocolConfig(
        max_rounds=max_rounds,
        max_turns_per_agent_per_round=max_turns_per_agent_per_round,
        convergence_threshold=convergence_threshold,
        max_total_tokens=max_total_tokens,
    )
    
    # Build scheduler config
    scheduler_config = SchedulerConfig(
        strategy=scheduling_strategy,
        max_consecutive_turns=max_consecutive_turns,
    )
    
    # Build workspace config
    config_kwargs = {
        "name": name,
        "description": description,
        "protocol_type": protocol_type,
        "protocol_config": protocol_config,
        "scheduler_config": scheduler_config,
        "max_rounds": max_rounds,
        "max_messages": max_messages,
        "max_total_tokens": max_total_tokens,
        "timeout_seconds": timeout_seconds,
        "auto_start": auto_start,
        "persist_state": persist_state,
        "display_messages": display_messages,
        "display_verbose": display_verbose,
        "on_message": on_message,
        "on_phase_change": on_phase_change,
        "on_round_end": on_round_end,
    }
    
    if workspace_id:
        config_kwargs["workspace_id"] = workspace_id
    
    config = WorkspaceConfig(**config_kwargs)
    engine = WorkspaceEngine(config)
    
    # If task and agents provided, initialize immediately
    if task and agents:
        import asyncio
        # We can't await here, so we'll return the engine and let user call run()
        # But we'll store the initialization params for auto-initialization
        engine._pending_init = {
            "task": task,
            "agents": agents,
            "context": context or {},
        }
    
    return engine


# Legacy helper functions for backwards compatibility
def create_consensus_workspace(
    name: str,
    message_handler: Optional[Callable] = None,
    max_rounds: int = 5,
    convergence: float = 0.8,
) -> WorkspaceEngine:
    """
    Quick consensus workspace creation (legacy).
    
    Note: Prefer using create_workspace() for new code.
    """
    return create_workspace(
        name=name,
        protocol="consensus",
        max_rounds=max_rounds,
        convergence_threshold=convergence,
        on_message=message_handler,
    )


def create_debate_workspace(
    name: str,
    message_handler: Optional[Callable] = None,
    max_rounds: int = 3,
) -> WorkspaceEngine:
    """
    Quick debate workspace creation (legacy).
    
    Note: Prefer using create_workspace() for new code.
    """
    return create_workspace(
        name=name,
        protocol="debate",
        max_rounds=max_rounds,
        on_message=message_handler,
    )


def create_critique_workspace(
    name: str,
    message_handler: Optional[Callable] = None,
    max_rounds: int = 3,
) -> WorkspaceEngine:
    """
    Quick critique-and-revise workspace creation (legacy).
    
    Note: Prefer using create_workspace() for new code.
    """
    return create_workspace(
        name=name,
        protocol="critique",
        max_rounds=max_rounds,
        on_message=message_handler,
    )


# Backwards compatibility alias
class WorkspaceBuilder:
    """
    Deprecated: Use create_workspace() instead.
    
    This class is kept for backwards compatibility but will be removed
    in a future version. Use the simpler create_workspace() function.
    """
    
    def __init__(self, name: str):
        raise DeprecationWarning(
            "WorkspaceBuilder is deprecated. Use create_workspace() instead:\n\n"
            "  workspace = create_workspace(\n"
            "      name='My Workspace',\n"
            "      task='My task',\n"
            "      agents=[agent1, agent2],\n"
            "      protocol='consensus',\n"
            "  )"
        )

