"""
User Memory REST API Blueprint

PRD section 12 — API Design:
    POST   /user-memory/store       — Extract & store from text, or store explicit node
    GET    /user-memory/recall      — Recall top memories for a user
    GET    /user-memory/prompt      — Return prompt-injection block
    DELETE /user-memory/{id}        — Delete a specific memory node
    DELETE /user-memory/user/{uid}  — Clear all memory for a user
    GET    /user-memory/count       — Count memories for a user
"""

import time
import logging
from flask import Blueprint, request, jsonify
from openmemo.user_memory import UserMemory

logger = logging.getLogger("openmemo.user_memory.api")


def create_user_memory_blueprint(db_path: str = "openmemo.db") -> Blueprint:
    bp = Blueprint("user_memory", __name__)
    um = UserMemory(db_path=db_path)

    # ── POST /user-memory/store ────────────────────────────────────────────────
    @bp.route("/user-memory/store", methods=["POST"])
    def store():
        """
        Extract & store user memory from text, or store an explicit node.

        Body (text extraction):
            { "user_id": "alice", "text": "I prefer FastAPI and avoid Kubernetes" }

        Body (explicit node):
            {
                "user_id": "alice",
                "type": "preference",
                "key": "backend",
                "value": "FastAPI",
                "confidence": 0.95,
                "source": "user_explicit"
            }
        """
        body = request.get_json(silent=True) or {}
        user_id = body.get("user_id", "default")

        t0 = time.time()

        # Explicit node mode
        if "key" in body and "value" in body:
            mem_type = body.get("type", "preference")
            if mem_type not in ("preference", "constraint", "environment", "behavior"):
                return jsonify({"error": "type must be preference|constraint|environment|behavior"}), 400
            key = body["key"].strip()
            value = body["value"].strip()
            if not key or not value:
                return jsonify({"error": "key and value required"}), 400
            mid = um.put(
                user_id=user_id,
                mem_type=mem_type,
                key=key,
                value=value,
                confidence=float(body.get("confidence", 0.9)),
                source=body.get("source", "user_explicit"),
            )
            return jsonify({
                "status": "stored",
                "memory_id": mid,
                "user_id": user_id,
                "latency_ms": round((time.time() - t0) * 1000, 1),
            }), 201

        # Text extraction mode
        text = body.get("text", "").strip()
        if not text:
            return jsonify({"error": "text or key+value required"}), 400

        ids = um.store(user_id, text)
        return jsonify({
            "status": "extracted",
            "stored": len(ids),
            "memory_ids": ids,
            "user_id": user_id,
            "latency_ms": round((time.time() - t0) * 1000, 1),
        }), 201

    # ── GET /user-memory/recall ────────────────────────────────────────────────
    @bp.route("/user-memory/recall", methods=["GET"])
    def recall():
        """
        Recall top user memories.

        Query params:
            user_id   — required
            top_n     — default 5
            type      — filter by type (optional)
        """
        user_id = request.args.get("user_id", "default")
        top_n = int(request.args.get("top_n", 5))
        mem_type = request.args.get("type", "")

        t0 = time.time()

        if mem_type:
            nodes = um._recall.recall(user_id, top_n=top_n, mem_type=mem_type)
            result = {
                mem_type: [n.to_dict() for n in nodes],
                "user_id": user_id,
            }
        else:
            result = um.to_dict(user_id, top_n=top_n)

        result["latency_ms"] = round((time.time() - t0) * 1000, 1)
        return jsonify(result)

    # ── GET /user-memory/prompt ────────────────────────────────────────────────
    @bp.route("/user-memory/prompt", methods=["GET"])
    def prompt():
        """
        Return the prompt-injection block for a user.

        Query params:
            user_id   — required
            top_n     — default 5

        Returns:
            { "prompt_block": "USER PROFILE\n..." }
        """
        user_id = request.args.get("user_id", "default")
        top_n = int(request.args.get("top_n", 5))

        t0 = time.time()
        block = um.format_for_prompt(user_id, top_n=top_n)
        return jsonify({
            "user_id": user_id,
            "prompt_block": block,
            "latency_ms": round((time.time() - t0) * 1000, 1),
        })

    # ── GET /user-memory/count ─────────────────────────────────────────────────
    @bp.route("/user-memory/count", methods=["GET"])
    def count():
        user_id = request.args.get("user_id", "default")
        return jsonify({"user_id": user_id, "count": um.count(user_id)})

    # ── DELETE /user-memory/<id> ───────────────────────────────────────────────
    @bp.route("/user-memory/<memory_id>", methods=["DELETE"])
    def delete_memory(memory_id: str):
        deleted = um.delete(memory_id)
        if deleted:
            return jsonify({"status": "deleted", "memory_id": memory_id})
        return jsonify({"error": "not found"}), 404

    # ── DELETE /user-memory/user/<uid> ─────────────────────────────────────────
    @bp.route("/user-memory/user/<user_id>", methods=["DELETE"])
    def delete_user(user_id: str):
        n = um.delete_user(user_id)
        return jsonify({"status": "cleared", "user_id": user_id, "deleted": n})

    return bp
