"""Download job endpoints (§A5). Heavy work is dispatched to arq workers — these
handlers only create/inspect/cancel/retry job records."""

import uuid

from fastapi import APIRouter, Query, Response

from app.api.deps import CurrentUser, DownloadServiceDep
from app.api.schemas.download import DownloadCreate, DownloadCreateResponse, DownloadJobOut
from app.api.schemas.pagination import PagedResponse

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


@router.get("")
async def list_downloads(
    service: DownloadServiceDep,
    user: CurrentUser,
    status: str | None = Query(default=None),
    mine: bool = Query(default=False),
    limit: int = Query(50, ge=1, le=200),
    offset: int = Query(0, ge=0),
) -> PagedResponse[DownloadJobOut]:
    jobs, total = await service.list(
        requested_by=user.id if mine else None,
        status=status,
        limit=limit,
        offset=offset,
    )
    return PagedResponse(
        items=[DownloadJobOut.from_entity(j) for j in jobs],
        total=total,
        limit=limit,
        offset=offset,
    )


@router.post("", status_code=202)
async def create_download(
    body: DownloadCreate,
    service: DownloadServiceDep,
    user: CurrentUser,
) -> DownloadCreateResponse:
    result = await service.request(
        source=body.source,
        source_id=body.source_id,
        query=body.query,
        requested_by=user.id,
    )
    return DownloadCreateResponse(
        already_in_library=result.already_in_library,
        track_id=result.track_id,
        job=DownloadJobOut.from_entity(result.job) if result.job is not None else None,
    )


@router.get("/{job_id}")
async def get_download(
    job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser
) -> DownloadJobOut:
    job = await service.get(job_id)
    return DownloadJobOut.from_entity(job)


@router.delete("/{job_id}", status_code=204)
async def cancel_download(
    job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser
) -> Response:
    await service.cancel(job_id)
    return Response(status_code=204)


@router.post("/{job_id}/retry")
async def retry_download(
    job_id: uuid.UUID, service: DownloadServiceDep, _: CurrentUser
) -> DownloadJobOut:
    job = await service.retry(job_id)
    return DownloadJobOut.from_entity(job)
