"""
aca/ai_engine/services/conversation_manager_patch.py

HOW TO INTEGRATE THE NEW SERVICES INTO ConversationManager
══════════════════════════════════════════════════════════

This file is a drop-in patch guide. It shows exactly where to import
and call the three new services inside your existing ConversationManager.

Paste the relevant snippets into your conversation_manager.py.
"""

# ─────────────────────────────────────────────────────────────────────────────
# 1. IMPORTS  (add to the top of conversation_manager.py)
# ─────────────────────────────────────────────────────────────────────────────

from .intent_layerer import enrich_query, build_prompt_context
from .attribute_weighter import rank_products
from .feedback_learner import get_user_context_summary


# ─────────────────────────────────────────────────────────────────────────────
# 2. INSIDE handle_message() or process_query()
#    (after slot extraction, before product search)
# ─────────────────────────────────────────────────────────────────────────────

def _patched_process_query(self, raw_text: str, slots: dict, request) -> dict:
    """
    Pseudocode showing the integration order.
    Replace the body of your existing process_query / handle_message method.
    """

    # ── Step 1: Intent Layering ──────────────────────────────────────
    # Enrich extracted slots with implicit intent signals from the raw text.
    # e.g. "winter coat for hiking" → adds purpose=hiking, season=winter,
    #      _intent_tags=["outdoor","cold-weather"], _boosted_attributes=[...]
    enriched_slots = enrich_query(slots, raw_text)

    # Optionally inject a context hint into the LLM system prompt
    intent_context_str = build_prompt_context(enriched_slots)
    # → pass intent_context_str into your LLM prompt builder

    # ── Step 2: Fetch learned user context ───────────────────────────
    # Pull preference signals from past feedback and interactions.
    user = request.user if request.user.is_authenticated else None
    session_key = request.session.session_key or ""
    user_context = get_user_context_summary(user=user, session_key=session_key)

    # ── Step 3: Fetch raw product results ────────────────────────────
    # Your existing search/filter logic — unchanged.
    raw_products = self._search_products(enriched_slots)

    # ── Step 4: Attribute Weighting ───────────────────────────────────
    # Re-rank products using stated priorities + learned signals.
    # The top results are returned first; each product gains a `_score` field.
    ranked_products = rank_products(
        products=raw_products,
        enriched_slots=enriched_slots,
        user_context=user_context,
        raw_text=raw_text,
    )

    # ── Step 5: Build response ────────────────────────────────────────
    # Pass ranked_products to your response builder as usual.
    return self._build_response(enriched_slots, ranked_products, intent_context_str)


# ─────────────────────────────────────────────────────────────────────────────
# 3. LLM PROMPT INJECTION (inside your prompt builder)
# ─────────────────────────────────────────────────────────────────────────────

SYSTEM_PROMPT_TEMPLATE = """
You are a helpful shopping assistant.

{intent_context}

{preference_context}

Answer the user's question and recommend the most relevant products.
"""

def build_system_prompt(intent_context_str: str, user_context: dict) -> str:
    """
    Injects intent and preference context into the system prompt so the LLM
    understands the user's purpose and past preferences.
    """
    preference_parts = []

    if user_context.get("preferred_brands"):
        brands = ", ".join(user_context["preferred_brands"][:5])
        preference_parts.append(f"User tends to prefer brands: {brands}.")

    if user_context.get("preferred_categories"):
        cats = ", ".join(user_context["preferred_categories"][:3])
        preference_parts.append(f"User often shops in: {cats}.")

    weights = user_context.get("attribute_weights", {})
    if weights:
        top = sorted(weights.items(), key=lambda x: x[1], reverse=True)[:3]
        attrs = ", ".join(f"{k} (weight {v:.1f})" for k, v in top)
        preference_parts.append(f"User values: {attrs}.")

    negative = user_context.get("recent_negative_interactions", [])
    if negative:
        neg_cats = list({p.get("category") for p in negative if p.get("category")})[:2]
        if neg_cats:
            preference_parts.append(
                f"User previously disliked products in: {', '.join(neg_cats)} — avoid over-recommending these."
            )

    return SYSTEM_PROMPT_TEMPLATE.format(
        intent_context=intent_context_str or "",
        preference_context="\n".join(preference_parts),
    ).strip()