"""Task management CLI commands"""

import asyncio
import json
from typing import Optional

import typer
from rich import print as rprint
from rich.table import Table

task_app = typer.Typer(name="task", help="Task management commands", no_args_is_help=True)


@task_app.command("submit")
def submit(
    input: Optional[str] = typer.Option(None, "--input", "-i", help="Input data as JSON string"),
    input_file: Optional[str] = typer.Option(None, "--input-file", "-f", help="Input data from JSON file"),
    skill: Optional[str] = typer.Option(None, "--skill", "-s", help="Skill name"),
    agent: Optional[str] = typer.Option(None, "--agent", "-a", help="Agent name"),
    mode: str = typer.Option("sync", "--mode", "-m", help="Execution mode: sync or async"),
    server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
    config: Optional[str] = typer.Option(None, "--config", help="Path to agentkit.yaml (local mode)"),
):
    """Submit a task for execution"""
    # Parse input data
    if input_file:
        with open(input_file, encoding="utf-8") as f:
            input_data = json.load(f)
    elif input:
        input_data = json.loads(input)
    else:
        rprint("[red]Error: Provide --input or --input-file[/red]")
        raise typer.Exit(code=1)

    if server_url:
        # Remote mode: use AgentKitClient
        _submit_remote(input_data, skill, agent, mode, server_url)
    else:
        # Local mode: execute directly
        _submit_local(input_data, skill, agent, mode, config)


def _submit_remote(input_data, skill, agent, mode, server_url):
    """Submit task to a remote AgentKit server."""
    from agentkit.server.client import AgentKitClient
    client = AgentKitClient(base_url=server_url)

    if mode == "async":
        result = asyncio.run(client.submit_task_async(
            input_data=input_data,
            skill_name=skill,
            agent_name=agent,
        ))
        rprint("[green]Task submitted (async)[/green]")
        rprint(f"  Task ID: {result.get('task_id', 'N/A')}")
        rprint(f"  Status: {result.get('status', 'N/A')}")
    else:
        result = asyncio.run(client.submit_task(
            input_data=input_data,
            skill_name=skill,
            agent_name=agent,
        ))
        rprint("[green]Task completed[/green]")
        if "output_data" in result:
            rprint(json.dumps(result["output_data"], indent=2, ensure_ascii=False))


def _submit_local(input_data, skill, agent, mode, config_path):
    """Submit task locally without a running server."""
    from agentkit.server.config import ServerConfig, find_config_path

    # Load config
    resolved_path = find_config_path(config_path)
    if resolved_path:
        server_config = ServerConfig.from_yaml(resolved_path)
        server_config.load_dotenv()
        server_config = ServerConfig.from_yaml(resolved_path)
    else:
        server_config = None

    # Build app components
    from agentkit.server.app import create_app
    app = create_app(server_config=server_config)

    # Execute task through the app's agent pool
    async def _execute():
        agent_pool = app.state.agent_pool
        skill_registry = app.state.skill_registry

        # Determine which skill/agent to use
        if skill:
            if not skill_registry.has_skill(skill):
                rprint(f"[red]Skill '{skill}' not found. Available: {[s.name for s in skill_registry.list_skills()]}[/red]")
                raise typer.Exit(code=1)
            skill_obj = skill_registry.get(skill)
            agent_name = skill_obj.name
        elif agent:
            agent_name = agent
        else:
            rprint("[red]Error: Provide --skill or --agent[/red]")
            raise typer.Exit(code=1)

        # Create agent and execute
        agent_instance = agent_pool.get_or_create(agent_name)
        from agentkit.core.protocol import TaskMessage, TaskStatus
        from datetime import datetime, timezone
        import uuid
        task = TaskMessage(
            task_id=str(uuid.uuid4()),
            agent_name=agent_name,
            task_type="cli_submit",
            priority=0,
            input_data=input_data,
            callback_url=None,
            created_at=datetime.now(timezone.utc),
        )
        result = await agent_instance.execute(task)
        return result

    result = asyncio.run(_execute())
    rprint("[green]Task completed[/green]")
    if result.output_data:
        rprint(json.dumps(result.output_data, indent=2, ensure_ascii=False, default=str))


@task_app.command("status")
def status(
    task_id: str = typer.Argument(help="Task ID"),
    server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
):
    """Get task status"""
    if not server_url:
        rprint("[red]Error: --server-url is required[/red]")
        raise typer.Exit(code=1)

    from agentkit.server.client import AgentKitClient
    client = AgentKitClient(base_url=server_url)
    result = asyncio.run(client.get_task_status(task_id))

    table = Table(title=f"Task: {task_id}")
    table.add_column("Field", style="cyan")
    table.add_column("Value")
    for key, value in result.items():
        table.add_row(key, str(value))
    rprint(table)


@task_app.command("list")
def list_tasks(
    status_filter: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status"),
    limit: int = typer.Option(100, "--limit", "-n", help="Maximum tasks to show"),
    server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
):
    """List tasks"""
    if not server_url:
        rprint("[red]Error: --server-url is required[/red]")
        raise typer.Exit(code=1)

    from agentkit.server.client import AgentKitClient
    client = AgentKitClient(base_url=server_url)
    tasks = asyncio.run(client.list_tasks(status=status_filter, limit=limit))

    if not tasks:
        rprint("[dim]No tasks found[/dim]")
        return

    table = Table(title="Tasks")
    table.add_column("Task ID", style="cyan")
    table.add_column("Agent")
    table.add_column("Status")
    table.add_column("Created")
    for t in tasks:
        table.add_row(
            t.get("task_id", ""),
            t.get("agent_name", ""),
            t.get("status", ""),
            t.get("created_at", ""),
        )
    rprint(table)


@task_app.command("cancel")
def cancel(
    task_id: str = typer.Argument(help="Task ID"),
    server_url: Optional[str] = typer.Option(None, "--server-url", help="AgentKit server URL"),
):
    """Cancel a running task"""
    if not server_url:
        rprint("[red]Error: --server-url is required[/red]")
        raise typer.Exit(code=1)

    from agentkit.server.client import AgentKitClient
    client = AgentKitClient(base_url=server_url)
    result = asyncio.run(client.cancel_task(task_id))
    rprint(f"[green]Task cancelled[/green]: {result}")
