from __future__ import annotations

import asyncio
import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException

from app.api.dependencies import get_orchestrator
from app.modules.auth.presentation.auth import get_current_user
from app.core.postgres.erp_client import ErpDatabaseClient
from app.models.schemas import (
    AgentRunRequest,
    AgentRunResponse,
    RouteTaskRequest,
    RouteTaskResponse,
)

logger = logging.getLogger("dscons.api.knowledge_agents.exec")
router = APIRouter()


def _log_agent_usage_safely(
    agent_code: str,
    task_type: str,
    query: str,
    answer: str,
    current_user: dict[str, Any] | None,
) -> None:
    """Ghi nhận nhật ký tiêu thụ token và ngân sách an toàn không chặn luồng chính."""
    try:
        user_email = (
            current_user.get("email") if isinstance(current_user, dict) else None
        )
        prompt_tokens = max(len(query.split()) * 2, 25)
        completion_tokens = max(len((answer or "").split()) * 2, 45)
        client = ErpDatabaseClient()
        client.log_ai_agent_usage(
            agent_code=agent_code,
            task_type=task_type,
            prompt_tokens=prompt_tokens,
            completion_tokens=completion_tokens,
            user_email=user_email,
            query_preview=query,
        )
    except Exception:
        pass


def _build_agent_run_response(result) -> AgentRunResponse:
    """Normalize orchestrator result into the public response model."""
    return AgentRunResponse(
        selected_agent=result.selected_agent,
        task_type=result.task_type,
        answer=result.answer,
        retrieved_chunks_count=result.retrieved_chunks_count,
        agent_code=result.agent_code,
    )


@router.post("/route-task", response_model=RouteTaskResponse)
def route_task(
    payload: RouteTaskRequest, current_user: dict[str, Any] = Depends(get_current_user)
) -> RouteTaskResponse:
    """Route a task through the orchestrator with persona-aware retrieval."""
    orchestrator = get_orchestrator()
    try:
        result = asyncio.run(
            orchestrator.route(
                task_type=payload.task_type,
                query=payload.query,
                top_k=payload.top_k,
                agent_code=payload.agent_code,
                retrieval_filters=payload.filters.model_dump(exclude_none=True)
                if payload.filters
                else None,
            )
        )
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc)) from exc

    _log_agent_usage_safely(
        agent_code=result.agent_code,
        task_type=result.task_type,
        query=payload.query,
        answer=result.answer,
        current_user=current_user,
    )

    return RouteTaskResponse(
        selected_agent=result.selected_agent,
        answer=result.answer,
        retrieved_chunks_count=result.retrieved_chunks_count,
        task_type=result.task_type,
        agent_code=result.agent_code,
    )


@router.post("/v1/agents/{task_type}/run", response_model=AgentRunResponse)
def run_agent(
    task_type: str,
    payload: AgentRunRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> AgentRunResponse:
    """Direct specialist execution endpoint for explicit task types."""
    orchestrator = get_orchestrator()
    try:
        result = asyncio.run(
            orchestrator.route(
                task_type=task_type,
                query=payload.query,
                top_k=payload.top_k,
                agent_code=payload.agent_code,
                retrieval_filters=payload.filters.model_dump(exclude_none=True)
                if payload.filters
                else None,
            )
        )
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc)) from exc

    _log_agent_usage_safely(
        agent_code=result.agent_code,
        task_type=result.task_type or task_type,
        query=payload.query,
        answer=result.answer,
        current_user=current_user,
    )

    return _build_agent_run_response(result)


@router.post("/v1/agents/by-code/{agent_code}/run", response_model=AgentRunResponse)
def run_agent_by_code(
    agent_code: str,
    payload: AgentRunRequest,
    current_user: dict[str, Any] = Depends(get_current_user),
) -> AgentRunResponse:
    """Run an AI employee persona directly using its default capability when needed."""
    orchestrator = get_orchestrator()
    try:
        result = asyncio.run(
            orchestrator.route(
                task_type="",
                query=payload.query,
                top_k=payload.top_k,
                agent_code=agent_code,
                retrieval_filters=payload.filters.model_dump(exclude_none=True)
                if payload.filters
                else None,
            )
        )
    except ValueError as exc:
        raise HTTPException(status_code=400, detail=str(exc)) from exc

    _log_agent_usage_safely(
        agent_code=result.agent_code,
        task_type=result.task_type or "persona_direct",
        query=payload.query,
        answer=result.answer,
        current_user=current_user,
    )

    return _build_agent_run_response(result)
