"""Query router for RAG pipeline."""
import logging

from fastapi import APIRouter, HTTPException

from app.core.config import get_settings
from app.models.query import QueryRequest, QueryResponse
from app.models.common import SourceMetadata
from app.services.llm_client import LLMClient
from app.services.query_decomposer import QueryDecomposer
from app.services.relevance_filter import RelevanceFilter
from app.services.rag import RAGService

logger = logging.getLogger(__name__)
router = APIRouter(tags=["query"])

NO_RESULTS_ANSWER = "I could not find any relevant information to answer your question."


@router.post("/query", response_model=QueryResponse)
async def query(request: QueryRequest):
    if not request.question or not request.question.strip():
        raise HTTPException(status_code=400, detail="Question is required")

    settings = get_settings()

    try:
        llm_client = LLMClient(settings)
        rag = RAGService(llm_client=llm_client, settings=settings)

        logger.info("Query: %s", request.question)
        decomposer = QueryDecomposer(llm_client)
        keywords = await decomposer.decompose(request.question)
        logger.info("Keywords: %s", keywords)

        chunks = rag.retrieve(keywords, n_results=settings.retrieval_n_results)

        if not chunks:
            return QueryResponse(keywords=keywords, answer=NO_RESULTS_ANSWER, sources=[])

        chunks_for_filter = [(text, meta) for text, meta, _dist in chunks]
        relevance_filter = RelevanceFilter(llm_client)
        filtered = await relevance_filter.filter(
            request.question, chunks_for_filter, threshold=settings.relevance_threshold
        )

        if not filtered:
            return QueryResponse(keywords=keywords, answer=NO_RESULTS_ANSWER, sources=[])

        chunk_texts = [chunk for chunk, _meta in filtered]
        chunk_metadata = [meta for _chunk, meta in filtered]

        answer = await rag.generate_response(request.question, chunk_texts, chunk_metadata)
        logger.info("Answer generated: %d chars, %d sources", len(answer), len(filtered))

        sources = [
            SourceMetadata(
                filename=meta.get("filename", "unknown"),
                upload_date=meta.get("upload_date", ""),
                content_summary=meta.get("content_summary", ""),
                chunk_index=meta.get("chunk_index", 0),
            )
            for meta in chunk_metadata
        ]

        return QueryResponse(keywords=keywords, answer=answer, sources=sources)

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Query failed: %s", str(e))
        raise HTTPException(status_code=500, detail=f"Query failed: {str(e)}")
