"""API router for the Spec Wizard — guided artifact generation."""

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

from hangar.dependencies import get_wizard_service
from hangar.services.wizard import SpecWizardService

router = APIRouter(prefix="/api/wizard", tags=["wizard"])


# ── Request/Response models ────────────────────────────────────────


class CreateRequest(BaseModel):
    name: str
    description: str


class CreateResponse(BaseModel):
    name: str
    path: str
    created: bool


class GenerateRequest(BaseModel):
    change_name: str
    artifact_type: str
    description: str
    approved_artifacts: dict[str, str]
    feedback: str | None = None
    agent_type: str = "claude-code"


class GenerateResponse(BaseModel):
    content: str
    agent_type: str
    prompt_used: str
    duration_ms: int


class ApproveRequest(BaseModel):
    change_name: str
    artifact_type: str
    content: str


class ApproveResponse(BaseModel):
    status: str


class StepStateResponse(BaseModel):
    artifact_type: str
    status: str
    content: str | None


class WizardStateResponse(BaseModel):
    change_name: str
    description: str | None
    steps: list[StepStateResponse]
    current_step: int


# ── Endpoints ──────────────────────────────────────────────────────


@router.post("/create")
async def create_change(
    body: CreateRequest,
    service: SpecWizardService = Depends(get_wizard_service),
) -> CreateResponse:
    """Create a new change directory for the wizard."""
    try:
        result = await service.create_change(body.name, body.description)
    except FileExistsError as e:
        raise HTTPException(status_code=409, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    return CreateResponse(
        name=result.name,
        path=result.path,
        created=result.created,
    )


@router.post("/generate")
async def generate_artifact(
    body: GenerateRequest,
    service: SpecWizardService = Depends(get_wizard_service),
) -> GenerateResponse:
    """Generate an artifact using an agent. Does NOT write to disk."""
    try:
        result = await service.generate_artifact(
            change_name=body.change_name,
            artifact_type=body.artifact_type,
            description=body.description,
            approved_artifacts=body.approved_artifacts,
            feedback=body.feedback,
            agent_type=body.agent_type,
        )
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))
    return GenerateResponse(
        content=result.content,
        agent_type=result.agent_type,
        prompt_used=result.prompt_used,
        duration_ms=result.duration_ms,
    )


@router.post("/approve")
async def approve_artifact(
    body: ApproveRequest,
    service: SpecWizardService = Depends(get_wizard_service),
) -> ApproveResponse:
    """Write approved artifact content to disk."""
    try:
        await service.approve_artifact(
            change_name=body.change_name,
            artifact_type=body.artifact_type,
            content=body.content,
        )
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    return ApproveResponse(status="approved")


@router.get("/{change_name}/state")
async def get_wizard_state(
    change_name: str,
    service: SpecWizardService = Depends(get_wizard_service),
) -> WizardStateResponse:
    """Get current wizard state for a change (derived from filesystem)."""
    try:
        state = await service.get_wizard_state(change_name)
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    return WizardStateResponse(
        change_name=state.change_name,
        description=state.description,
        steps=[
            StepStateResponse(
                artifact_type=s.artifact_type,
                status=s.status,
                content=s.content,
            )
            for s in state.steps
        ],
        current_step=state.current_step,
    )
