import logging
import httpx
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
from app.schemas.spec import ProjectSpec
from app.llm.prompts import PM_AGENT_PROMPT
from app.core.config import settings

logger = logging.getLogger(__name__)
sync_client = httpx.Client(verify=False)
async_client = httpx.AsyncClient(verify=False)

async def run_pm_agent(user_input: str, history: list | None = None) -> ProjectSpec:
    """Agent PM qui remplit ProjectSpec en analysant le besoin utilisateur."""

    llm = ChatOpenAI(
        base_url=settings.llm_base_url,
        api_key=settings.llm_api_key,
        model=settings.llm_model,
        temperature=0.3,
        max_retries=2,
        http_client=sync_client,
        http_async_client=async_client,
    )
    structured_llm = llm.with_structured_output(ProjectSpec, strict=True)
    
    messages = [
        SystemMessage(content=PM_AGENT_PROMPT),
    ]
    
    if history:
        messages.extend(history)
    
    messages.append(HumanMessage(
        content=f"""En te basant sur TOUT l'historique de notre conversation et sur cette dernière précision, génère le JSON ProjectSpec valide et complètement rempli.

DERNIÈRE PRÉCISION / INPUT UTILISATEUR :
{user_input}

IMPORTANT : Tu dois impérativement combiner les contraintes énoncées précédemment (comme le langage de programmation choisi, l'OS, etc.) avec cette nouvelle information pour enrichir la spécification existante.
Réponds UNIQUEMENT avec du JSON valide. Aucun texte avant le JSON, aucun texte après le JSON."""
    ))
        
    try:
        project_spec = await structured_llm.ainvoke(messages)
        logger.info(f"[PM Agent] ✅ Tentative réussie (Structured Output)")
        project_spec = _validate_and_sanitize(project_spec, user_input)
        return project_spec
        
    except Exception as e2:
        logger.error(f"[PM Agent] ❌ Tentative échouée: {type(e2).__name__}: {str(e2)}")
        logger.info("[PM Agent] Fallback: Génération automatique du spec")
        
        return _generate_fallback_spec(user_input)

def _validate_and_sanitize(spec: ProjectSpec, user_input: str) -> ProjectSpec:
    """
    Fait confiance au LLM pour la logique métier.
    Se contente de s'assurer de la cohérence technique minimale.
    """
    logger.debug(f"[Sanitize] Validation du spec généré pour : {spec.title}")
    
    # 1. Sécurité minimale sur les chaînes de texte vides
    if not spec.title or spec.title.lower() in ["null", "none", ""]:
        spec.title = "Automation Script"
        
    if not spec.description:
        spec.description = f"Script d'automatisation basé sur : {user_input[:50]}..."

    # 2. Gestion de la complétude :
    if not spec.is_complete or (spec.clarifying_question and spec.clarifying_question.strip()):
        spec.is_complete = False
        if not spec.clarifying_question:
            spec.clarifying_question = "Pourriez-vous apporter plus de précisions sur les actions que doit effectuer ce script ?"
        logger.info(f"[Sanitize] Le besoin est qualifié d'INCOMPLET par l'agent PM.")
    else:
        spec.is_complete = True
        spec.clarifying_question = None
        logger.info(f"[Sanitize] Le besoin est qualifié de COMPLET par l'agent PM.")

    return spec

def _generate_fallback_spec(user_input: str) -> ProjectSpec:
    """Génère un ProjectSpec par défaut en cas d'erreur complète."""
    
    logger.warning(f"[Fallback] Génération d'un spec par défaut pour: {user_input}")
    
    return ProjectSpec(
        title="Automation Script",
        description=f"Automatisation du besoin utilisateur: {user_input}",
        requirements=[
            f"Exécuter l'action demandée: {user_input}",
            "Gérer les erreurs",
            "Générer des logs"
        ],
        constraints=["PEP 8 strict"],
        language="Python",
        target_stack="",
        io_config={
            "has_inputs": False,
            "input_type": "none",
            "input_paths_or_sources": [],
            "has_outputs": False,
            "output_type": "log_only",
            "output_formats": []
        },
        auth_config={
            "requires_auth": False,
            "auth_method": "none",
            "target_tools_and_apis": []
        },
        env_config={
            "target_os": "cross_platform",
            "language_version": "3.11",
            "critical_dependencies": ["logging"]
        },
        error_handling_strategy="log_and_continue",
        is_complete=False,
        clarifying_question="Pourriez-vous donner plus de détails sur votre demande ?"
    )