"""API router for specialist inference endpoints.

All endpoints live under /api/specialist/ prefix for consistency with
the broader Intelligence Pipeline v3 routing conventions.
"""

from __future__ import annotations

import time

from fastapi import APIRouter, HTTPException

from services.specialist.models import (
    BatchResponse,
    ClassificationRequest,
    ExtractionRequest,
)

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

# Engine is injected at app startup via app.state
_engine = None


def set_engine(engine) -> None:  # noqa: ANN001
    """Set the engine reference used by all route handlers."""
    global _engine
    _engine = engine


def _get_engine():
    """Get the current engine or raise 503."""
    if _engine is None or not _engine.is_ready:
        raise HTTPException(status_code=503, detail="Specialist engine not ready")
    return _engine


# ---------------------------------------------------------------------------
# Entity extraction
# ---------------------------------------------------------------------------


@router.post("/entities", response_model=BatchResponse)
async def extract_entities(request: ExtractionRequest) -> BatchResponse:
    """Batch entity extraction — returns spans with character offsets and scores."""
    engine = _get_engine()

    if len(request.texts) > engine.max_batch_size:
        raise HTTPException(
            status_code=422,
            detail=f"Batch size {len(request.texts)} exceeds maximum {engine.max_batch_size}",
        )

    start = time.perf_counter()
    results = engine.extract_entities(request.texts, request.schema_labels)
    elapsed_ms = (time.perf_counter() - start) * 1000

    return BatchResponse(
        results=results,
        model_version=engine.model_name,
        schema_version="specialist-v1",
        processing_time_ms=round(elapsed_ms, 2),
        batch_id=request.batch_id,
    )


# ---------------------------------------------------------------------------
# Event classification
# ---------------------------------------------------------------------------


@router.post("/classify", response_model=BatchResponse)
async def classify_events(request: ClassificationRequest) -> BatchResponse:
    """Batch event classification — returns labels with confidence scores."""
    engine = _get_engine()

    if len(request.texts) > engine.max_batch_size:
        raise HTTPException(
            status_code=422,
            detail=f"Batch size {len(request.texts)} exceeds maximum {engine.max_batch_size}",
        )

    start = time.perf_counter()
    results = engine.classify_texts(request.texts, request.schema_labels)
    elapsed_ms = (time.perf_counter() - start) * 1000

    return BatchResponse(
        results=results,
        model_version=engine.model_name,
        schema_version="specialist-v1",
        processing_time_ms=round(elapsed_ms, 2),
        batch_id=request.batch_id,
    )


# ---------------------------------------------------------------------------
# Relation extraction
# ---------------------------------------------------------------------------


@router.post("/relations", response_model=BatchResponse)
async def extract_relations(request: ExtractionRequest) -> BatchResponse:
    """Batch relation extraction — returns subject-relation-object triples with spans."""
    engine = _get_engine()

    if len(request.texts) > engine.max_batch_size:
        raise HTTPException(
            status_code=422,
            detail=f"Batch size {len(request.texts)} exceeds maximum {engine.max_batch_size}",
        )

    start = time.perf_counter()
    results = engine.extract_relations(request.texts, request.schema_labels)
    elapsed_ms = (time.perf_counter() - start) * 1000

    return BatchResponse(
        results=results,
        model_version=engine.model_name,
        schema_version="specialist-v1",
        processing_time_ms=round(elapsed_ms, 2),
        batch_id=request.batch_id,
    )


# ---------------------------------------------------------------------------
# Structured extraction
# ---------------------------------------------------------------------------


@router.post("/extract", response_model=BatchResponse)
async def extract_structured(request: ExtractionRequest) -> BatchResponse:
    """Structured fact extraction — returns key-value pairs with spans."""
    engine = _get_engine()

    if len(request.texts) > engine.max_batch_size:
        raise HTTPException(
            status_code=422,
            detail=f"Batch size {len(request.texts)} exceeds maximum {engine.max_batch_size}",
        )

    start = time.perf_counter()
    results = engine.extract_structured(request.texts, request.schema_labels)
    elapsed_ms = (time.perf_counter() - start) * 1000

    return BatchResponse(
        results=results,
        model_version=engine.model_name,
        schema_version="specialist-v1",
        processing_time_ms=round(elapsed_ms, 2),
        batch_id=request.batch_id,
    )
