"""
AI SQL Trace API — Thin FastAPI route layer.

All business logic lives in agent/sql_agent/.
This file only handles HTTP routing, auth, and SSE response formatting.
"""

import logging

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from starlette.responses import StreamingResponse

from agent.sql_agent.persistence import load_conversation_detail, load_conversations
from agent.sql_agent.session_manager import (approve_session, delete_session, get_session, list_sessions,
                                             public_session, reject_session)
from agent.sql_agent.trace_agent import run_trace_agent
from auth.middleware import get_current_user

logger = logging.getLogger(__name__)
router = APIRouter()


class AISQLTraceRequest(BaseModel):
    question: str
    model: str = "codex/gpt-5.3-codex"
    max_cycles: int = Field(default=4, ge=1, le=4)
    conversation_id: str | None = None


class ApprovalRequest(BaseModel):
    action: str = Field(..., pattern="^(accept|reject)$")


# ─── Main Trace Endpoint ─────────────────────────────────────────────

@router.post("/api/ai-sql/trace", summary="AI SQL Trace Agent (SSE Stream)")
async def ai_sql_trace_stream(req: AISQLTraceRequest, user: dict = Depends(get_current_user)):
    user_codex_token = user.get("settings", {}).get("codex_token")
    user_openai_key = user.get("settings", {}).get("openai_key")

    return StreamingResponse(
        run_trace_agent(
            question=req.question,
            model=req.model,
            max_cycles=req.max_cycles,
            conversation_id=req.conversation_id,
            codex_token=user_codex_token,
            openai_key=user_openai_key,
        ),
        media_type="text/event-stream",
    )


# ─── Approval Endpoint (Human-in-the-Loop) ───────────────────────────

@router.post("/api/ai-sql/approve/{session_id}", summary="Approve or reject pending SQL")
async def approve_ai_sql(session_id: int, req: ApprovalRequest, user: dict = Depends(get_current_user)):
    if req.action == "accept":
        ok = approve_session(session_id)
    else:
        ok = reject_session(session_id)

    if not ok:
        return {"error": "No pending approval for this session", "success": False}
    return {"success": True, "action": req.action}


# ─── Session Management Endpoints ────────────────────────────────────

@router.get("/api/ai-sql/sessions", summary="List AI SQL trace sessions")
async def list_ai_sql_sessions(user: dict = Depends(get_current_user)):
    return {"sessions": list_sessions()}


@router.get("/api/ai-sql/sessions/{session_id}", summary="Get AI SQL trace session detail")
async def get_ai_sql_session(session_id: int, user: dict = Depends(get_current_user)):
    session = get_session(session_id)
    if not session:
        return {"error": "Session not found"}
    return {"session": public_session(session)}


@router.delete("/api/ai-sql/sessions/{session_id}", summary="Delete AI SQL trace session")
async def delete_ai_sql_session(session_id: int, user: dict = Depends(get_current_user)):
    if not delete_session(session_id):
        return {"error": "Session not found"}
    return {"success": True}


# ─── Conversation History Endpoints ──────────────────────────────────

@router.get("/api/ai-sql/conversations", summary="List SQL trace conversations")
async def list_sql_conversations(user: dict = Depends(get_current_user)):
    conversations = load_conversations()
    return {"conversations": conversations}


@router.get("/api/ai-sql/conversations/{conv_id}", summary="Get SQL trace conversation detail")
async def get_sql_conversation(conv_id: str, user: dict = Depends(get_current_user)):
    sessions = load_conversation_detail(conv_id)
    return {"conversation_id": conv_id, "sessions": sessions}
