from fastapi import APIRouter, BackgroundTasks, HTTPException

from app.core.env import env_bool
from app.models.document import IngestRequest, IngestResponse
from app.models.parse_run import ParseRunStatus
from app.repositories import parse_run_repo
from app.services import ingestion_service
from app.services.ingestion_queue_service import enqueue_ingestion_job
from app.services.repo_docs_sync_service import ingest_repo_docs
from app.workers.ingestion_worker import run_ingestion_job

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


@router.post("/", response_model=IngestResponse, status_code=202)
async def ingest_document(
    request: IngestRequest,
    background_tasks: BackgroundTasks,
) -> IngestResponse:
    """
    Queue a repository document for parsing and chunking.
    Returns immediately with a `run_id`; poll `/ingest/status/{run_id}` to track progress.
    """
    run = await ingestion_service.create_parse_run(request)

    queued = env_bool("QUEUE_ENABLED", True)

    if queued:
        try:
            await enqueue_ingestion_job(run.run_id, request)
        except Exception as exc:
            raise HTTPException(status_code=502, detail=str(exc)) from exc
    else:
        background_tasks.add_task(run_ingestion_job, run.run_id, request)

    return IngestResponse(
        run_id=run.run_id,
        status=ParseRunStatus.QUEUED if queued else ParseRunStatus.PENDING,
        message=f"Queued: {request.doc_path}",
    )


@router.get("/status/{run_id}")
async def get_ingestion_status(run_id: str):
    """Retrieve the status and result of an ingestion run."""
    run = await parse_run_repo.get_run_by_id(run_id)
    if not run:
        raise HTTPException(status_code=404, detail="Run not found")
    return run


@router.post("/repos/{repo_id:path}/docs/sync")
async def ingest_repo_docs_folder(repo_id: str):
    """Ingest all markdown files under docs/ for a synced repository."""
    try:
        result = await ingest_repo_docs(repo_id)
    except RuntimeError as exc:
        raise HTTPException(status_code=502, detail=str(exc)) from exc
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    if result["total_docs_found"] == 0:
        return {
            "repo_id": repo_id,
            "message": "No markdown files found under docs/",
            **result,
        }

    return {
        "repo_id": repo_id,
        "message": "Docs markdown ingestion completed",
        **result,
    }