"""
Context Timeline — Captures and manages key session events.

PRD §8 — Timeline Generation:
    Events captured on: on_agent_step, on_tool_call, on_decision
    Event types: decision | action | result | error
"""

import time
import logging
from typing import List, Optional
from openmemo.context_memory.context_store import (
    ContextStore, TimelineEvent
)

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

VALID_TYPES = {"decision", "action", "result", "error"}


class ContextTimeline:
    """
    Records timeline events for a session.

    Usage:
        timeline = ContextTimeline(store)
        timeline.add("session_1", "action", "Docker image built successfully")
        timeline.add("session_1", "decision", "Chose docker-compose over Kubernetes")
        events = timeline.get_top("session_1", limit=5)
    """

    def __init__(self, store: ContextStore):
        self.store = store

    # ── Write ──────────────────────────────────────────────────────────────────

    def add(self, session_id: str, event_type: str,
            content: str) -> Optional[str]:
        """
        Record a timeline event.

        event_type: "decision" | "action" | "result" | "error"
        Returns event_id or None if content is empty.
        """
        if not content or not content.strip():
            return None
        if event_type not in VALID_TYPES:
            event_type = "action"

        event = TimelineEvent(
            session_id=session_id,
            type=event_type,
            content=content.strip()[:500],
        )
        eid = self.store.add_event(event)
        logger.debug("timeline: session=%s type=%s", session_id, event_type)
        return eid

    def on_agent_step(self, session_id: str, step_text: str) -> Optional[str]:
        """PRD §8.1 — Capture agent step as 'action' event."""
        return self.add(session_id, "action", step_text)

    def on_tool_call(self, session_id: str, tool_name: str,
                     result: str) -> Optional[str]:
        """PRD §8.1 — Capture tool call as 'action' event."""
        content = f"tool:{tool_name} → {result}"
        return self.add(session_id, "action", content)

    def on_decision(self, session_id: str, decision: str) -> Optional[str]:
        """PRD §8.1 — Capture a decision."""
        return self.add(session_id, "decision", decision)

    def on_result(self, session_id: str, result: str) -> Optional[str]:
        """Capture a task result."""
        return self.add(session_id, "result", result)

    def on_error(self, session_id: str, error: str) -> Optional[str]:
        """Capture an error event."""
        return self.add(session_id, "error", error)

    # ── Read ───────────────────────────────────────────────────────────────────

    def get_top(self, session_id: str, limit: int = 5) -> List[TimelineEvent]:
        """Return the N most recent timeline events (PRD §9.2)."""
        return self.store.get_recent_events(session_id, limit=limit)

    def get_all(self, session_id: str) -> List[TimelineEvent]:
        """Return full timeline (chronological order)."""
        return self.store.get_timeline(session_id)

    def format_for_prompt(self, session_id: str, limit: int = 5) -> str:
        """
        Format top timeline events as a compact prompt block.

        Example:
            Timeline:
              [action] Docker image built
              [decision] Use docker-compose
        """
        events = self.get_top(session_id, limit=limit)
        if not events:
            return ""
        lines = ["Timeline:"]
        for ev in events:
            lines.append(f"  [{ev.type}] {ev.content}")
        return "\n".join(lines)

    def count(self, session_id: str) -> int:
        return self.store.count_events(session_id)
