import os
import json
import logging
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
from config.settings import settings
from agent.utils.mcp_helper import safe_invoke_tool
from agent.prompts.dax_prompts import get_dax_ub_presupuesto_prompt

logger = logging.getLogger(__name__)

async def ub_presupuesto_skill_node(state):
    """
    Nodo de ejecución EXCLUSIVO para tableros de Ventas y Utilidad Bruta vs Presupuesto.
    Transforma la consulta NL a DAX y ejecuta la herramienta de UB/Presupuesto.
    """
    prompt_usuario = state["messages"][-1].content
    user_name = state.get("user_name", "Desconocido")
    user_position = state.get("user_position", "")
    chat_history = state.get("messages", [])[:-1]
    
    llm = ChatOpenAI(model=settings.MODEL_NAME, temperature=0)
    
    # Construir contexto de usuario
    user_context = f"Usuario actual: {user_name}"
    if user_position:
        user_context += f" ({user_position})"
    
    history_str = "\n".join([f"{m.type}: {m.content}" for m in chat_history[-5:]])
    
    # Carga de la Base de Conocimiento (Hot Reload)
    kb_content = ""
    try:
        kb_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "DOCUMENTACION", "KB_Modelo_UB_Presupuesto.md")
        with open(kb_path, 'r', encoding='utf-8') as f:
            kb_content = f.read()
    except Exception as e:
        logger.warning(f"No se pudo cargar KB de UB Presupuesto: {e}")

    full_system_prompt = f"{user_context}\n\n=== HISTORIAL ===\n{history_str}\n\n{get_dax_ub_presupuesto_prompt()}\n\n=== DOCUMENTACIÓN DEL MODELO ===\n{kb_content}"
    
    logger.info("⚙️ Skill activada: UB_PRESUPUESTO (ub_presupuesto_skill)")
    dax_response = await llm.ainvoke([
        SystemMessage(content=full_system_prompt),
        HumanMessage(content=prompt_usuario)
    ])
    
    dax_code = dax_response.content.strip()
    # Sanitizar: quitar bloques de markdown
    import re
    dax_code = re.sub(r'^```[\w]*\n?', '', dax_code, flags=re.MULTILINE).strip()
    dax_code = re.sub(r'```$', '', dax_code, flags=re.MULTILINE).strip()
    
    # NUEVO: Extraer solo lo que empieza con EVALUATE si hay texto extra
    if "EVALUATE" in dax_code.upper():
        match = re.search(r'(EVALUATE.*)', dax_code, re.IGNORECASE | re.DOTALL)
        if match:
            dax_code = match.group(1).strip()
            
    logger.info(f"📄 DAX generada (sanitizada):\n{dax_code}")
    
    # Manejar respuestas directas
    if "DIRECT_RESPONSE:" in dax_code:
        final_answer = dax_code.replace("DIRECT_RESPONSE:", "").strip()
        return {"messages": [AIMessage(content=final_answer)]}

    # 2. Invocar la herramienta en el servidor Java MCP específica para este tablero
    logger.info("🚀 DAX enviada a TOOL: consultarAgrotaUbPresupuesto")
    args = {"dax": dax_code}
    resultado = await safe_invoke_tool("consultarAgrotaUbPresupuesto", args)

    # 3. Actualizar la cola y retornar resultados
    pendientes = state.get("intenciones_pendientes", [])
    if "UB_PRESUPUESTO" in pendientes:
        pendientes.remove("UB_PRESUPUESTO")
        
    return {
        "resultados_tecnicos": [json.dumps(resultado, ensure_ascii=False)],
        "intenciones_pendientes": pendientes,
        "mensaje_skill": "Datos obtenidos de UB_PRESUPUESTO",
        "dashboard": "UB_PRESUPUESTO",
        "dax_query": dax_code
    }
