"""
UI Controller — Unified interface for all user-visible Memory UI components.

Controls five UI components:
  1. Activation Panel   — shown on install
  2. Memory Rule Card   — shows current memory policy
  3. Insight Card       — Memory Created / Optimization Detected
  4. Reuse Indicator    — ⚡ Reusing past experience
  5. Guided First Task  — first-run guidance

All methods return a structured card dict suitable for:
  - HTTP API responses (Inspector endpoints)
  - Logging (adapter uses logger.info)
  - Future UI integrations (GUI, CLI, webhooks)

Performance target: UI response < 100ms
"""

import time
import threading
import logging
from typing import Optional, List, Dict, Any

logger = logging.getLogger("openmemo_openclaw")

CARD_TYPES = frozenset([
    "activation_panel",
    "rule_card",
    "insight_memory_created",
    "insight_optimization_detected",
    "reuse_indicator",
    "guided_first_task",
])


class UIController:
    """
    Central controller for all user-visible Memory UI cards.

    Cards are immutable dicts. Once generated they are stored in a
    history list for later retrieval via the Inspector API.

    Usage:
        ui = UIController()
        card = ui.show_activation(panel_payload)
        card = ui.show_rule_card(policy_engine)
        card = ui.show_insight(insight_payload)
        card = ui.show_reuse_indicator("Deploy workflow reused")
    """

    def __init__(self):
        self._lock = threading.Lock()
        self._cards: List[dict] = []
        self._current_card: Optional[dict] = None

    # ── Public API ──────────────────────────────────────────────────────────

    def show_activation(self, payload: dict) -> dict:
        """
        Show Activation Panel.
        Triggered on_install — informs user the system is active.
        """
        card = {
            "type": "activation_panel",
            "title": payload.get("title", "✅ OpenMemo Activated"),
            "subtitle": payload.get("subtitle", "Your agent now has memory."),
            "what_happens": payload.get("what_happens", [
                "Tasks will be remembered",
                "Workflows will be reused",
                "Performance improves over time",
            ]),
            "actions": payload.get("actions", []),
            "ts": int(time.time() * 1000),
        }
        self._push(card)
        logger.info("[ui] activation_panel: %s", card["title"])
        return card

    def show_rule_card(self, policy_engine=None) -> dict:
        """
        Show Memory Rule Card.
        Displays current policy in user-readable format.
        """
        if policy_engine:
            rc = policy_engine.get_rule_card()
        else:
            rc = {
                "mode": "Smart Memory Mode",
                "tagline": "We remember what works, not what doesn't.",
                "we_remember": ["successful tasks", "reusable workflows", "your preferences"],
                "we_ignore": ["failed attempts", "temporary steps"],
            }
        card = {
            "type": "rule_card",
            "title": f"Memory Mode: {rc.get('mode', 'Smart Memory Mode')}",
            "tagline": rc.get("tagline", ""),
            "we_remember": rc.get("we_remember", []),
            "we_ignore": rc.get("we_ignore", []),
            "ts": int(time.time() * 1000),
        }
        self._push(card)
        logger.info("[ui] rule_card: mode=%s remember=%d ignore=%d",
                    rc.get("mode"), len(card["we_remember"]), len(card["we_ignore"]))
        return card

    def show_insight(self, insight: dict) -> dict:
        """
        Show Insight Card (Memory Created or Optimization Detected).
        Triggered after task completion by the Insight Engine.
        """
        itype = insight.get("type", "memory_created")
        card = {
            "type": f"insight_{itype}",
            "title": insight.get("title", "🧠 Memory Created"),
            "items": insight.get("items", []),
            "body": insight.get("body", ""),
            "task_id": insight.get("task_id", ""),
            "ts": int(time.time() * 1000),
        }
        self._push(card)
        logger.info("[ui] insight_card: %s | items=%d", card["title"], len(card["items"]))
        return card

    def show_reuse_indicator(self, workflow_summary: str = "",
                             task_id: str = "") -> dict:
        """
        Show Reuse Indicator.
        Triggered when a workflow is adopted (workflow_reuse event).
        """
        card = {
            "type": "reuse_indicator",
            "title": "⚡ Reusing past experience",
            "body": workflow_summary or "A previously successful workflow is being applied.",
            "task_id": task_id,
            "ts": int(time.time() * 1000),
        }
        self._push(card)
        logger.info("[ui] reuse_indicator: %s", workflow_summary[:60] if workflow_summary else "")
        return card

    def show_guided_first_task(self, task_id: str = "",
                               query: str = "") -> dict:
        """
        Show Guided First Task card.
        Triggered on first task start.
        """
        card = {
            "type": "guided_first_task",
            "title": "Try your first task",
            "body": query or "Deploy a backend service",
            "hint": "Run it twice to see the difference.",
            "task_id": task_id,
            "ts": int(time.time() * 1000),
        }
        self._push(card)
        logger.info("[ui] guided_first_task: %s", card["body"][:60])
        return card

    # ── State Accessors ─────────────────────────────────────────────────────

    def get_current_card(self) -> Optional[dict]:
        """Return the most recently shown card."""
        with self._lock:
            return self._current_card

    def get_all_cards(self, limit: int = 50) -> List[dict]:
        """Return all generated cards (most recent first)."""
        with self._lock:
            return list(reversed(self._cards[-limit:]))

    def get_cards_by_type(self, card_type: str) -> List[dict]:
        """Return cards of a specific type."""
        with self._lock:
            return [c for c in self._cards if c.get("type") == card_type]

    def get_stats(self) -> Dict[str, Any]:
        """Return UI interaction stats."""
        with self._lock:
            by_type: Dict[str, int] = {}
            for c in self._cards:
                t = c.get("type", "unknown")
                by_type[t] = by_type.get(t, 0) + 1
            return {
                "total_cards": len(self._cards),
                "by_type": by_type,
                "current_card_type": self._current_card.get("type") if self._current_card else None,
            }

    # ── Internal ────────────────────────────────────────────────────────────

    def _push(self, card: dict) -> None:
        with self._lock:
            self._cards.append(card)
            self._current_card = card
