"""
Timeline Builder — Builds chronological event stream for Inspector.

PRD §4.4 — Timeline output:
[
    {
        "timestamp": "2026-03-30T10:00:00Z",
        "event":     "memory_recalled",
        "memory_id": "mem_123",
        "summary":   "Recalled workflow:deploy|fastapi|docker-compose"
    },
    ...
]

PRD §5.3 — Build logic:
    events = get_all_events(task_id)
    sort_by_time(events)
    return format(events)
"""

import time
import logging
from typing import List, Optional
from openmemo.feedback_aggregator.utils import to_iso

logger = logging.getLogger("openmemo.aggregator")

# Event type constants
EV_RECALLED  = "memory_recalled"
EV_INJECTED  = "memory_injected"
EV_ADOPTED   = "memory_adopted"
EV_SUCCESS   = "task_succeeded"
EV_FAILED    = "task_failed"
EV_WF_REC    = "workflow_recommended"
EV_WF_ADOPT  = "workflow_adopted"
EV_WF_DONE   = "workflow_completed"


class TimelineBuilder:
    """
    Builds a chronological event stream for a task or memory.

    Usage:
        builder = TimelineBuilder(feedback_store)
        timeline = builder.build_for_task("task_001")
        timeline = builder.build_for_memory("mem_123")
        timeline = builder.build_global(limit=50)
    """

    def __init__(self, feedback_store):
        self._store = feedback_store

    # ── PRD §5.3 Task Timeline ─────────────────────────────────────────────────

    def build_for_task(self, task_id: str) -> List[dict]:
        """
        PRD §5.3 — Build timeline for a specific task.

        Merges memory feedback + workflow feedback events, sorted by time.
        """
        t0 = time.time()
        events = []

        # Memory feedback events
        mem_records = self._store.get_task_feedback(task_id)
        for r in mem_records:
            if r.recalled:
                events.append(self._mem_event(r, EV_RECALLED,
                    f"Recalled memory:{r.memory_id} layer:{r.memory_layer or 'unknown'}"))
            if r.injected:
                events.append(self._mem_event(r, EV_INJECTED,
                    f"Injected memory:{r.memory_id} tokens:{r.token_size} pos:{r.position or '-'}"))
            if r.adopted:
                events.append(self._mem_event(r, EV_ADOPTED,
                    f"Adopted memory:{r.memory_id}"))
            if r.success:
                events.append(self._mem_event(r, EV_SUCCESS,
                    f"Task {task_id} succeeded (memory:{r.memory_id})"))

        # Workflow feedback events
        try:
            wf_rows = self._store.conn.execute(
                "SELECT * FROM workflow_feedback WHERE task_id=? ORDER BY timestamp ASC",
                (task_id,)
            ).fetchall()
            for row in wf_rows:
                if row["recommended"]:
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": EV_WF_REC,
                        "workflow_id": row["workflow_id"],
                        "memory_id": None,
                        "agent_id": row["agent_id"],
                        "summary": f"Recommended workflow:{row['workflow_id']}",
                    })
                if row["adopted"]:
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": EV_WF_ADOPT,
                        "workflow_id": row["workflow_id"],
                        "memory_id": None,
                        "agent_id": row["agent_id"],
                        "summary": f"Adopted workflow:{row['workflow_id']} rate:{row['adoption_rate']:.0%}",
                    })
                if row["success"] is not None:
                    ev = EV_WF_DONE
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": ev,
                        "workflow_id": row["workflow_id"],
                        "memory_id": None,
                        "agent_id": row["agent_id"],
                        "summary": (
                            f"Workflow completed: {'success' if row['success'] else 'failed'} "
                            f"time:{row['completion_time']:.0f}s"
                        ),
                    })
        except Exception as e:
            logger.debug("timeline wf query: %s", e)

        # Sort by timestamp
        events.sort(key=lambda e: e.get("_ts", 0))

        # Strip internal sort key
        for e in events:
            e.pop("_ts", None)

        elapsed = (time.time() - t0) * 1000
        logger.debug("timeline task=%s events=%d ms=%.1f", task_id, len(events), elapsed)
        return events

    # ── Memory Timeline ────────────────────────────────────────────────────────

    def build_for_memory(self, memory_id: str, limit: int = 50) -> List[dict]:
        """Build timeline for all events related to a specific memory."""
        t0 = time.time()
        records = self._store.get_memory_feedback(memory_id, limit=limit)
        events = []
        for r in records:
            if r.recalled:
                events.append(self._mem_event(r, EV_RECALLED,
                    f"Recalled in task:{r.task_id}"))
            if r.injected:
                events.append(self._mem_event(r, EV_INJECTED,
                    f"Injected tokens:{r.token_size} pos:{r.position or '-'}"))
            if r.adopted:
                events.append(self._mem_event(r, EV_ADOPTED,
                    f"Adopted in task:{r.task_id}"))
            if r.success:
                events.append(self._mem_event(r, EV_SUCCESS,
                    f"Led to success in task:{r.task_id}"))

        events.sort(key=lambda e: e.get("_ts", 0))
        for e in events:
            e.pop("_ts", None)

        elapsed = (time.time() - t0) * 1000
        logger.debug("timeline mem=%s events=%d ms=%.1f", memory_id, len(events), elapsed)
        return events

    # ── Global Timeline ────────────────────────────────────────────────────────

    def build_global(self, limit: int = 100) -> List[dict]:
        """
        Build a recent global event timeline across all tasks/memories.
        """
        t0 = time.time()
        events = []

        try:
            mem_rows = self._store.conn.execute("""
                SELECT * FROM memory_feedback
                ORDER BY timestamp DESC LIMIT ?
            """, (limit,)).fetchall()

            for row in mem_rows:
                if row["recalled"]:
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": EV_RECALLED,
                        "memory_id": row["memory_id"],
                        "task_id": row["task_id"],
                        "agent_id": row["agent_id"],
                        "summary": f"Recalled memory:{row['memory_id']} task:{row['task_id']}",
                    })
                if row["adopted"]:
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": EV_ADOPTED,
                        "memory_id": row["memory_id"],
                        "task_id": row["task_id"],
                        "agent_id": row["agent_id"],
                        "summary": f"Adopted memory:{row['memory_id']}",
                    })

            wf_rows = self._store.conn.execute("""
                SELECT * FROM workflow_feedback
                ORDER BY timestamp DESC LIMIT ?
            """, (limit,)).fetchall()

            for row in wf_rows:
                if row["adopted"]:
                    events.append({
                        "timestamp": to_iso(row["timestamp"]),
                        "_ts": row["timestamp"],
                        "event": EV_WF_ADOPT,
                        "workflow_id": row["workflow_id"],
                        "task_id": row["task_id"],
                        "memory_id": None,
                        "summary": f"Workflow reused:{row['workflow_id']} task:{row['task_id']}",
                    })

        except Exception as e:
            logger.warning("build_global error: %s", e)

        events.sort(key=lambda e: e.get("_ts", 0), reverse=True)
        for e in events:
            e.pop("_ts", None)

        elapsed = (time.time() - t0) * 1000
        logger.debug("timeline global events=%d ms=%.1f", len(events[:limit]), elapsed)
        return events[:limit]

    # ── Helper ─────────────────────────────────────────────────────────────────

    def _mem_event(self, record, event_type: str, summary: str) -> dict:
        return {
            "timestamp": to_iso(record.timestamp),
            "_ts": record.timestamp,
            "event": event_type,
            "memory_id": record.memory_id,
            "task_id": record.task_id,
            "agent_id": record.agent_id,
            "summary": summary,
        }
