"""
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 typing import Any

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

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

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}
