"""Polleo AI — conversational analytics router.

Mounted in main.py under {API_PREFIX}/polleo-ai with a global
Depends(get_current_user). The /chat endpoint additionally gates on the
`polleo_ai` section (require_section), matching the finance/executive pattern.

The feature is OPTIONAL: when ANTHROPIC_API_KEY is unset, /health reports
"not_configured" and /chat returns 503 — the page degrades gracefully.
"""
from __future__ import annotations

import json
import logging
from collections.abc import Iterator

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import StreamingResponse

from backend.api.middleware.auth import CurrentUser, require_section
from backend.schemas.polleo_ai import ChatRequest, ChatResponse, HealthResponse
from backend.services import polleo_ai_service as svc

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/polleo-ai", tags=["polleo-ai"])


def _sse(payload: dict) -> str:
    # jsonable_encoder converts Decimal->float, date->iso (so chart numbers stay numeric).
    return f"data: {json.dumps(jsonable_encoder(payload), ensure_ascii=False)}\n\n"


@router.get("/health", response_model=HealthResponse)
def health() -> HealthResponse:
    return HealthResponse(status="ok" if svc.is_configured() else "not_configured")


@router.post("/chat", response_model=ChatResponse)
def chat(
    body: ChatRequest,
    _: CurrentUser = Depends(require_section("polleo_ai")),
) -> ChatResponse:
    try:
        return svc.chat(body.message, body.conversation_history)
    except svc.PolleoAiNotConfigured:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="Polleo AI is not configured.",
        )
    except svc.ClaudeTimeoutError:
        raise HTTPException(
            status_code=status.HTTP_504_GATEWAY_TIMEOUT,
            detail="Odgovor je trajao predugo. Pokušaj jednostavnije pitanje.",
        )
    except svc.ClaudeApiError as exc:
        logger.warning("Polleo AI upstream error: %s", exc)
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail="Nisam uspio dohvatiti odgovor. Pokušaj ponovno za koji trenutak.",
        )


@router.post("/chat/stream")
def chat_stream(
    body: ChatRequest,
    _: CurrentUser = Depends(require_section("polleo_ai")),
) -> StreamingResponse:
    """Same agentic answer as /chat, but streamed as Server-Sent Events so the
    UI can show progress: a `step` event per executed query, then a `final`
    event with the answer + data + chart, or an `error` event."""
    if not svc.is_configured():
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="Polleo AI is not configured.",
        )

    def gen() -> Iterator[str]:
        try:
            for ev in svc.run_agentic(body.message, body.conversation_history):
                if ev.get("type") == "final":
                    resp: ChatResponse = ev["response"]
                    yield _sse({"type": "final", **resp.model_dump()})
                else:
                    yield _sse(ev)
        except svc.ClaudeTimeoutError:
            yield _sse({"type": "error", "detail": "Odgovor je trajao predugo. Pokušaj jednostavnije pitanje."})
        except svc.ClaudeApiError as exc:
            logger.warning("Polleo AI upstream error (stream): %s", exc)
            yield _sse({"type": "error", "detail": "Nisam uspio dohvatiti odgovor. Pokušaj ponovno za koji trenutak."})
        except Exception:  # noqa: BLE001 — never leak a stack trace into the stream
            logger.exception("Polleo AI stream failed")
            yield _sse({"type": "error", "detail": "Došlo je do greške. Pokušaj ponovno."})

    return StreamingResponse(
        gen(),
        media_type="text/event-stream",
        headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"},
    )
