from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Request, status

from ai_orchestrator.schemas.task_request import TaskRequest
from ai_orchestrator.schemas.task_result import TaskResultResponse
from ai_orchestrator.schemas.task_status import TaskStatusResponse, TaskSubmittedResponse
from ai_orchestrator.services.task_service import TaskService

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


def get_task_service(request: Request) -> TaskService:
    return request.app.state.task_service


@router.post("/tasks", response_model=TaskSubmittedResponse, status_code=status.HTTP_202_ACCEPTED)
async def submit_task(
    payload: TaskRequest,
    task_service: TaskService = Depends(get_task_service),
) -> TaskSubmittedResponse:
    try:
        return await task_service.submit_task(payload)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc


@router.get("/tasks/{task_id}", response_model=TaskStatusResponse)
async def get_status(
    task_id: str,
    task_service: TaskService = Depends(get_task_service),
) -> TaskStatusResponse:
    task = await task_service.get_status(task_id)
    if task is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Task not found.")
    return task


@router.get("/tasks/{task_id}/result", response_model=TaskResultResponse)
async def get_result(
    task_id: str,
    task_service: TaskService = Depends(get_task_service),
) -> TaskResultResponse:
    try:
        result = await task_service.get_result(task_id)
    except RuntimeError as exc:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc
    if result is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Task not found.")
    return result


@router.post("/tasks/{task_id}/cancel", response_model=TaskStatusResponse)
async def cancel_task(
    task_id: str,
    task_service: TaskService = Depends(get_task_service),
) -> TaskStatusResponse:
    status_response = await task_service.cancel_task(task_id)
    if status_response is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Task not found.")
    return status_response
