"""
Arcádia MiroFlow Service — Agentes científicos via MiroFlow + Ollama local
FastAPI microserviço porta 8006
"""
import os
import sys
import time
import uuid
from typing import Optional

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

# Adicionar o submodule MiroFlow ao path
MIROFLOW_MODULE_PATH = os.path.join(
    os.path.dirname(__file__), "..", "modules", "miroflow"
)
sys.path.insert(0, os.path.abspath(MIROFLOW_MODULE_PATH))

from miroflow.agents.factory import build_agent
from miroflow.agents.context import AgentContext

OLLAMA_BASE_URL = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434")
RESEARCHER_MODEL = os.getenv("MIROFLOW_RESEARCHER_MODEL", "llama3.1:8b")

AGENT_MODELS = {
    "statistician": "llama3.2:3b",
    "fiscal_auditor": "llama3.2:3b",
    "researcher": RESEARCHER_MODEL,
}


def make_agent_cfg(agent_type: str) -> dict:
    model = AGENT_MODELS.get(agent_type, "deepseek-r1:14b")
    return {
        "type": "IterativeAgentWithToolAndRollback",
        "name": f"arcadia_{agent_type}",
        "max_turns": 10,
        "llm": {
            "provider_class": "UnifiedOpenAIClient",
            "model_name": model,
            "api_key": "ollama",
            "base_url": f"{OLLAMA_BASE_URL}/v1",
            "max_tokens": 8192,
            "temperature": 0.7,
            "top_p": 1.0,
            "min_p": 0.0,
            "top_k": -1,
            "reasoning_effort": None,
            "repetition_penalty": 1.0,
            "max_context_length": -1,
            "async_client": True,
            "disable_cache_control": True,
            "keep_tool_result": -1,
            "use_tool_calls": False,
            "oai_tool_thinking": False,
        },
    }


async def run_agent(agent_type: str, task: str) -> tuple[str, str]:
    """Retorna (result_text, model_name)"""
    if agent_type not in AGENT_MODELS:
        raise ValueError(f"Agente desconhecido: {agent_type}. Use: {list(AGENT_MODELS.keys())}")
    cfg = make_agent_cfg(agent_type)
    agent = build_agent(cfg)
    ctx = AgentContext(
        task_description=task,
        system_prompt=(
            "Você é um agente científico da Arcádia Suite especializado em análise de dados "
            "empresariais. Responda em português de forma clara e objetiva. "
            "Quando precisar de dados, explique o que analisaria e quais conclusões seriam esperadas."
        ),
        initial_user_message=task,
    )
    result = await agent.run(ctx)
    if isinstance(result, dict):
        text = (
            result.get("summary")
            or result.get("final_boxed_answer")
            or result.get("exceed_max_turn_summary")
            or next(
                (m["content"] for m in reversed(result.get("message_history") or []) if m.get("role") == "assistant"),
                None,
            )
            or str(result)
        )
    else:
        text = str(result)
    return text, cfg["llm"]["model_name"]


app = FastAPI(title="Arcádia MiroFlow Service", version="1.0.0")
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


class AnalyzeRequest(BaseModel):
    agent: str
    task: str
    context: dict = {}
    tenant_id: Optional[int] = None


class AnalyzeResponse(BaseModel):
    agent: str
    model: str
    result: str
    execution_id: str
    duration_ms: int


@app.get("/health")
async def health_check():
    return {"status": "ok", "service": "miroflow", "agents": list(AGENT_MODELS.keys())}


@app.post("/analyze", response_model=AnalyzeResponse)
async def analyze(req: AnalyzeRequest):
    if req.agent not in AGENT_MODELS:
        raise HTTPException(status_code=422, detail=f"Agente inválido: {req.agent}")
    start = time.time()
    try:
        result_text, model_name = await run_agent(req.agent, req.task)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
    return AnalyzeResponse(
        agent=req.agent,
        model=model_name,
        result=result_text,
        execution_id=str(uuid.uuid4()),
        duration_ms=int((time.time() - start) * 1000),
    )


if __name__ == "__main__":
    import uvicorn
    port = int(os.environ.get("MIROFLOW_PORT", 8006))
    uvicorn.run(app, host="0.0.0.0", port=port)
