"""Assistant blueprint — SAP HANA + Gemini conversational AI."""
import json, logging, os, time, uuid, traceback
import requests
from flask import Blueprint, jsonify, Response, request, session, stream_with_context
from blueprints.sap import execute_hana_query_flow

logger = logging.getLogger("apex")
assistant_bp = Blueprint("assistant", __name__)

_SAP_KEYWORDS = [
    "sales","revenue","stock","inventory","branch","product","customer","region","brand",
    "order","po","purchase","invoice","payment","pending","transit","ageing","aging",
    "dispatch","material","sku","plant","today","month","year","ytd","qtd","top","best",
    "performance","cr","lakh","crore","total","compare","breakdown","summary","report",
    "rashi","rptechindia","asus","lenovo","dell","hp","acer","samsung","jbl",
]

def _is_sap_query(text: str) -> bool:
    lo = text.lower()
    return any(kw in lo for kw in _SAP_KEYWORDS)

def _wrap_ans(answer):
    return {"answer": answer, "data": [], "result": [], "module": "home",
            "trace_id": uuid.uuid4().hex[:12], "artifacts": [], "warnings": [], "next_actions": []}

def _gemini_chat(user_input: str, sap_context: str = "") -> str:
    api_key = os.getenv("GEMINI_CHAT_KEY", "")
    if not api_key: return ""
    system = """You are Apex, the internal AI assistant for RPTech India (Rashi Peripherals Limited).
You assist employees with sales data analysis, inventory queries, purchase orders, and general work questions.
Guidelines:
- Be concise, friendly, and professional
- For casual greetings, respond warmly and briefly
- Never make up company data — only use provided SAP context
- Use ₹ Cr for revenue values. Do not ask for clarification if data is already provided."""

    prompt = system
    if sap_context: prompt += f"\n\nLive SAP Data:\n{sap_context}"
    prompt += f"\n\nUser: {user_input}\nApex:"
    payload = {"contents": [{"parts": [{"text": prompt}]}], "generationConfig": {"temperature": 0.7, "maxOutputTokens": 800}}

    for attempt in range(3):
        try:
            res = requests.post(
                f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={api_key}",
                json=payload, timeout=15)
            data = res.json()
            candidates = data.get("candidates", [])
            if not candidates:
                code = data.get("error", {}).get("code", 0)
                if code == 503:
                    logger.warning("[Gemini] 503 busy, retry %d/3", attempt+1)
                    time.sleep(2 ** attempt); continue
                if code == 429:
                    return "⚠️ AI assistant is temporarily unavailable (daily limit reached). Please try again tomorrow."
                logger.warning("[Gemini] No candidates: %s", data)
                return ""
            return candidates[0]["content"]["parts"][0]["text"]
        except Exception as e:
            logger.warning("[Gemini] Error attempt %d: %s", attempt+1, e)
            if attempt == 2: return ""
    return ""

def _get_conv_store():
    from extensions import conversation_store
    return conversation_store

def _check_user_rate_limit(email: str) -> bool:
    """Returns True if user is within 1500 req/day limit."""
    try:
        import extensions as ext
        from datetime import datetime
        from zoneinfo import ZoneInfo
        day = datetime.now(tz=ZoneInfo("Asia/Kolkata")).strftime("%Y%m%d")
        key = f"rl:{email}:{day}"
        count = ext.redis_client.get(key)
        count = int(count) if count else 0
        if count >= 1500: return False
        ext.redis_client.set(key, count + 1, ex=86400)
        return True
    except: return True  # fail open

def _handle_chat(data):
    user_input = (data.get("input", "") or "").strip()
    if not user_input: return {"error": "No input provided"}, 400

    session_token = session.get("user", "anon")
    conv_store = _get_conv_store()

    # Check rate limit
    if not _check_user_rate_limit(session_token):
        return _wrap_ans("⚠️ You've reached your daily limit of 1500 requests. Please try again tomorrow!"), 200

    # Get conversation history for context
    history = ""
    if conv_store:
        history = conv_store.format_for_prompt(session_token)

    # Non-SAP → Gemini with history
    if not _is_sap_query(user_input):
        ctx = f"Conversation history:\n{history}" if history else ""
        answer = _gemini_chat(user_input, ctx) or "Hey! I'm Apex, RPTech's AI assistant. Ask me about sales, inventory, or company performance!"
        if conv_store: conv_store.add_turn(session_token, user_input, answer)
        return _wrap_ans(answer), 200

    try:
        hana_payload, status_code = execute_hana_query_flow(user_input)

        if status_code >= 400 or hana_payload.get("error"):
            ctx = f"Conversation history:\n{history}" if history else ""
            answer = _gemini_chat(user_input, ctx) or "Could not fetch SAP data. Please try again."
            if conv_store: conv_store.add_turn(session_token, user_input, answer)
            return _wrap_ans(answer), 200

        hana_rows = hana_payload.get("result") or []
        if not hana_rows:
            ctx = f"Conversation history:\n{history}" if history else ""
            answer = _gemini_chat(user_input, ctx) or "No matching data found in SAP HANA."
            if conv_store: conv_store.add_turn(session_token, user_input, answer)
            return _wrap_ans(answer), 200

        # HANA has data — pass history + data to Gemini
        ctx = ""
        if history: ctx += f"Conversation history:\n{history}\n\n"
        ctx += (f"The user asked: '{user_input}'\n"
                f"SAP HANA returned {len(hana_rows)} rows.\n"
                f"Data (first 10 rows): {json.dumps(hana_rows[:10], default=str)}\n\n"
                f"Summarize clearly. Use ₹ Cr for revenue. Do not ask for clarification.")
        answer = _gemini_chat(user_input, ctx)

        if conv_store:
            conv_store.add_turn(session_token, user_input, answer or hana_payload.get("answer", ""))

        hana_payload.update({
            "answer": answer or hana_payload.get("answer", ""),
            "data": hana_rows, "module": "sales", "module_label": "SAP HANA",
            "trace_id": uuid.uuid4().hex[:12], "artifacts": [], "warnings": [], "next_actions": [],
        })
        return hana_payload, status_code

    except Exception as exc:
        logger.error("[Assistant] Chat error: %s\n%s", exc, traceback.format_exc())
        return {"error": f"Assistant error: {exc}"}, 500

# ── Routes ─────────────────────────────────────────────────────────────────────
@assistant_bp.route("/sales/chat", methods=["POST"])
@assistant_bp.route("/assistant/chat", methods=["POST"])
def sales_chat():
    payload, code = _handle_chat(request.get_json() or {})
    return jsonify(payload), code

@assistant_bp.route("/sales/history", methods=["GET"])
def sales_history():
    conv_store = _get_conv_store()
    turns = conv_store.get_history(session.get("user", "anon")) if conv_store else []
    return jsonify({"history": turns, "count": len(turns)})

@assistant_bp.route("/sales/history", methods=["DELETE"])
def clear_sales_history():
    conv_store = _get_conv_store()
    if conv_store: conv_store.clear(session.get("user", "anon"))
    return jsonify({"cleared": True})

@assistant_bp.route("/assistant/stream", methods=["POST"])
def assistant_stream():
    body = request.get_json(silent=True) or {}
    user_message = (body.get("message") or "").strip()
    if not user_message: return jsonify({"error": "message is required"}), 400
    def _generate():
        try:
            answer = _gemini_chat(user_message)
            for word in (answer or "No response available.").split(" "):
                yield f"data: {json.dumps({'token': word+' '})}\n\n"
        except Exception as exc:
            yield f"data: {json.dumps({'error': str(exc)})}\n\n"
        finally:
            yield "data: [DONE]\n\n"
    return Response(stream_with_context(_generate()), mimetype="text/event-stream",
                    headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"})