from typing import Optional
from uuid import UUID

import typer

from cli.commands.knowledge.documents.bulk_reingest_failed.presenter import (
    present_bulk_reingest_failed_result,
)
from cli.infrastructure.command import async_command, authenticated_client
from alloy_runtime_types.dtos.knowledge import BulkReingestFailedDocumentsRequest


def knowledge_documents_bulk_reingest_failed_command(
    dry_run: bool = typer.Option(
        False,
        "--dry-run",
        help="Preview which failed documents would be requeued",
    ),
    collection: Optional[str] = typer.Option(
        None,
        "-C",
        "--collection",
        help="Optional collection UUID to scope the bulk reingest",
    ),
    document_ids: Optional[list[str]] = typer.Option(
        None,
        "--document-id",
        help="Document UUID to include. Repeat to scope multiple documents.",
    ),
) -> None:
    _execute_bulk_reingest_failed(
        dry_run=dry_run,
        collection=collection,
        document_ids=document_ids,
    )


def _parse_uuid_option(value: str, option_name: str) -> UUID:
    try:
        return UUID(value)
    except ValueError as exc:
        raise typer.BadParameter(f"Invalid UUID for {option_name}: {value}") from exc


@async_command
async def _execute_bulk_reingest_failed(
    dry_run: bool,
    collection: Optional[str],
    document_ids: Optional[list[str]],
) -> None:
    collection_id = (
        _parse_uuid_option(collection, "--collection")
        if collection is not None
        else None
    )
    parsed_document_ids = (
        [
            _parse_uuid_option(document_id, "--document-id")
            for document_id in document_ids
        ]
        if document_ids
        else None
    )

    request = BulkReingestFailedDocumentsRequest(
        dry_run=dry_run,
        collection_id=collection_id,
        document_ids=parsed_document_ids,
    )

    async with authenticated_client() as (_config, client):
        response = await client.bulk_reingest_failed_documents(request)

    present_bulk_reingest_failed_result(response)
