import logging
from typing import List

import json
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, Field
from sse_starlette.sse import EventSourceResponse

from app.api.dependencies import get_orchestrator
from app.core.security import verify_supabase_jwt
from app.services.chatbot.langgraph_orchestrator import LangGraphPRALOrchestrator

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/chat", tags=["Agentic Chatbot"])


class AgenticChatRequest(BaseModel):
    query: str = Field(..., description="Pertanyaan dari pengguna yang akan diproses oleh asisten AI.")
    project_id: str = Field(..., description="ID sesi/proyek unik untuk menjaga riwayat percakapan.")
    active_hashes: List[str] = Field(default=[], description="Daftar Hash dari dokumen PDF yang sedang dibuka/dipilih oleh pengguna (sebagai jangkar utama).")
    mode: str = Field(default="STRICT", description="Mode chatbot: STRICT atau RESEARCH")
    has_used_research: bool = Field(default=False, description="Apakah pengguna sudah pernah menggunakan mode RESEARCH di sesi ini.")


@router.post("/stream", summary="Stream Jawaban Chatbot Berdasarkan Artikel Aktif")
async def stream_chat(
    request: AgenticChatRequest,
    orchestrator: LangGraphPRALOrchestrator = Depends(get_orchestrator),
    user_id: str = Depends(verify_supabase_jwt),
):
    """Stream chatbot responses backed by the LangGraph PRAL runtime."""
    if not request.query.strip():
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Query tidak boleh kosong.",
        )

    logger.info(
        "Menerima request chat untuk project %s dengan konteks hashes %s dari user %s",
        request.project_id,
        request.active_hashes,
        user_id,
    )

    async def stream_generator():
        try:
            async for text_chunk in orchestrator.process_chat(
                request.query,
                request.active_hashes,
                request.project_id,
                user_id,
                request.mode,
                request.has_used_research,
            ):
                try:
                    # Parse string output from orchestrator into dict for SSE format
                    event_dict = json.loads(text_chunk.strip())
                    yield event_dict
                except json.JSONDecodeError:
                    yield {"event": "chunk", "data": json.dumps({"text": text_chunk.strip()})}
        except Exception as exc:
            logger.error("Error pada stream generator LangGraph: %s", exc)
            yield {
                "event": "error",
                "data": json.dumps({"message": f"Maaf, terjadi kesalahan saat memproses respons: {str(exc)}", "code": 500})
            }

    return EventSourceResponse(stream_generator())
