"""Dispatch and prompt-preview endpoints."""

from typing import Any

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field

from proxym.dashboard._environments_api import get_tool_environment_snapshot
from proxym.tools import ToolRegistry
from proxym.dashboard.tools._helpers import _get_ticket, _default_project_dir

router = APIRouter(tags=["tools"])


class DispatchRequest(BaseModel):
    ticket_id: str = Field(..., description="Ticket ID to dispatch")
    tool: str = Field(..., description="Tool name (aider, claude-code, ...)")
    mode: str = Field("", description="Agent mode (code, architect, debug, ask)")
    model: str = Field("", description="Model alias or full name")
    project_dir: str = Field("", description="Project directory")


class PreviewPromptRequest(BaseModel):
    ticket_id: str = Field(..., description="Ticket ID")
    tool: str = Field(..., description="Tool name")
    mode: str = Field("", description="Agent mode")


@router.post("/prompt/preview")
async def preview_prompt(req: PreviewPromptRequest) -> dict[str, Any]:
    """Preview the prompt that would be sent to a tool for a ticket."""
    tool = ToolRegistry.get().get_tool(req.tool)
    if not tool:
        raise HTTPException(404, f"Tool '{req.tool}' not found")

    from proxym.tools.prompt_builder import build_prompt_dict
    ticket = _get_ticket(req.ticket_id)
    return build_prompt_dict(ticket, tool, req.mode)


@router.post("/dispatch")
async def dispatch_job(req: DispatchRequest) -> dict[str, Any]:
    """Dispatch a tool to work on a ticket. Enqueues a job."""
    tool = ToolRegistry.get().get_tool(req.tool)
    if not tool:
        raise HTTPException(404, f"Tool '{req.tool}' not found")

    ticket = _get_ticket(req.ticket_id)
    if tool.name == "human":
        from proxym.dashboard._tickets_api import _tickets
        from proxym.dashboard.tickets import ToolAssignment

        mgr = _tickets()
        mgr.assign_tool(ticket.id, ToolAssignment(tool=tool.name, agent_mode=req.mode, model=req.model))
        updated = mgr.get_ticket(ticket.id)
        return {
            "job": None,
            "ticket": updated.summary() if updated else ticket.summary(),
            "message": f"Human task assigned for ticket {ticket.id}",
        }

    environment = get_tool_environment_snapshot(req.tool)
    project_dir = req.project_dir or (environment.get("path") if environment else "") or _default_project_dir(ticket.project_id)

    from proxym.tools.executor import ToolExecutor
    executor = ToolExecutor.get()
    # Make dispatch self-contained: if the worker isn't running yet, start it
    # before enqueueing so the job doesn't stay queued forever.
    await executor.start()
    job = executor.enqueue(ticket, tool, project_dir, req.mode, req.model, environment=environment)
    return {"job": job.summary(), "message": f"Job {job.id} enqueued for {tool.name}"}
