import logging
from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy.orm import Session
from starlette.concurrency import run_in_threadpool
from enterprise_ai.core.database import get_db
from enterprise_ai.core.auth import get_current_user

logger = logging.getLogger(__name__)

from enterprise_ai.agents.catalog import AGENT_ROUTES, route_prefix
from enterprise_ai.core.execution import parse_agent_form, run_execution
from enterprise_ai.core.intent import resolve_intent
from enterprise_ai.schemas.executes import ExecuteResponse, ExecutionDetail
from enterprise_ai.models.initiative import MAIinitiative
from enterprise_ai.models.bot import MAIbot
from enterprise_ai.models.execution import TAIexecution

router = APIRouter(prefix="/api/ai", tags=["AI"])


@router.post(
    "/execute",
    response_model=ExecuteResponse,
    summary="Execute an AI capability with automatic agent routing",
    openapi_extra={
        "requestBody": {
            "content": {
                "multipart/form-data": {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "input":      {"type": "string", "description": "Text input"},
                            "session_id": {"type": "string", "description": "Session ID"},
                            "bot_hint":   {"type": "string", "description": "Route hint: 'chatbot', 'chatinterface', 'applicant', 'generate_profile', 'document_identifier', or 'parse_validate'"},
                            "login":      {"type": "string", "description": "GoodBooks Login JSON (required for chatbot)"},
                            "file":       {"type": "string", "format": "binary", "description": "File upload"},
                        },
                    }
                }
            }
        }
    }
)
async def execute_ai(
    request: Request,
    db: Session = Depends(get_db),
    current_user: dict = Depends(get_current_user)
):
    tenantId = current_user["tenantId"]
    userId = current_user["userId"]

    parsed = await parse_agent_form(request, tenantId, userId)

    # Intent resolution and execution are both blocking (DB + outbound HTTP),
    # so they run off the event loop — see the note in api/agents.py.
    execution, result = await run_in_threadpool(
        _resolve_and_execute, db, tenantId, userId, parsed
    )

    return ExecuteResponse(
        executionId=execution.AIexecutionid,
        result=result
    )


def _resolve_and_execute(db: Session, tenantId: int, userId: int, parsed):
    # Auto-resolve capabilityCode + botCode from input
    capabilityCode, botCode = resolve_intent(
        db, tenantId, parsed.input_text, parsed.file, parsed.session_id, parsed.bot_hint
    )

    if not capabilityCode:
        raise HTTPException(status_code=400, detail="Unable to detect capability from input")

    if not botCode:
        raise HTTPException(status_code=400, detail="No active bot found for detected capability")

    # Auto-resolve initiativeCode from botCode
    bot_lookup = db.query(MAIbot).filter(
        MAIbot.AIbotcode == botCode,
        MAIbot.TENANTID == tenantId
    ).first()
    if not bot_lookup:
        raise HTTPException(status_code=400, detail="Invalid Bot")

    initiative_lookup = db.query(MAIinitiative).filter(
        MAIinitiative.aiinitiativeid == bot_lookup.AIinitiativeid,
        MAIinitiative.tenantid == tenantId
    ).first()
    if not initiative_lookup:
        raise HTTPException(status_code=400, detail="Invalid Initiative")

    return run_execution(
        db,
        tenantId,
        userId,
        initiative_lookup.aiinitiativecode,
        capabilityCode,
        parsed.input_data,
        parsed.file,
        bot_code=botCode,
    )


@router.get("/agents", summary="List every agent and its dedicated URL")
def list_agents(current_user: dict = Depends(get_current_user)):
    prefix = route_prefix()

    return {
        "agents": [
            {
                "slug":               entry.slug,
                "url":                f"{prefix}/{entry.slug}",
                "aliases":            [f"{prefix}/{a}" for a in entry.aliases],
                "initiativeCode":     entry.initiative_code,
                "defaultCapability":  entry.default_capability,
                "capabilities":       list(entry.all_capabilities),
                "acceptsFile":        entry.accepts_file,
                "acceptsText":        entry.accepts_text,
                "requiresFile":       entry.requires_file,
                "summary":            entry.summary,
            }
            for entry in AGENT_ROUTES
        ]
    }


@router.get("/execution/{execution_id}", response_model=ExecutionDetail)
def get_execution(
    execution_id: int,
    db: Session = Depends(get_db),
    current_user: dict = Depends(get_current_user)
):
    execution = db.query(TAIexecution).filter(
        TAIexecution.AIexecutionid == execution_id,
        TAIexecution.tenantid == current_user["tenantId"]
    ).first()

    if not execution:
        raise HTTPException(status_code=404, detail="Execution not found")

    return execution
