"""
Feedback Aggregator — Main facade orchestrating all 4 builder types.

PRD §14 — Design principle:
    "Aggregator's job is not to record, but to explain what happened."

PRD §2 — System position:
    Feedback Loop → Feedback Aggregator → Inspector API → UI/CLI
"""

import logging
from typing import List, Optional
from openmemo.feedback_aggregator.task_trace_builder import TaskTraceBuilder
from openmemo.feedback_aggregator.memory_profile_builder import MemoryProfileBuilder
from openmemo.feedback_aggregator.metrics_builder import MetricsBuilder
from openmemo.feedback_aggregator.timeline_builder import TimelineBuilder

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


class FeedbackAggregator:
    """
    Unified aggregation facade for the Feedback → Inspector bridge.

    Usage:
        from openmemo.feedback_aggregator import FeedbackAggregator
        from openmemo.memory_feedback import FeedbackStore

        store = FeedbackStore("openmemo.db")
        agg = FeedbackAggregator(store)

        trace   = agg.task_trace("task_001")
        profile = agg.memory_profile("mem_123")
        metrics = agg.impact_metrics()
        timeline = agg.timeline("task_001")
    """

    def __init__(self, feedback_store):
        self._store = feedback_store
        self._trace_builder   = TaskTraceBuilder(feedback_store)
        self._profile_builder = MemoryProfileBuilder(feedback_store)
        self._metrics_builder = MetricsBuilder(feedback_store)
        self._timeline_builder = TimelineBuilder(feedback_store)

    # ── §4.1 Task Trace ────────────────────────────────────────────────────────

    def task_trace(self, task_id: str) -> dict:
        """
        PRD §4.1 — Build current task chain trace for Inspector.

        Returns complete trace with recalled/injected/adopted memories,
        workflow used, and task outcome.
        """
        return self._trace_builder.build(task_id)

    # ── §4.2 Memory Profile ────────────────────────────────────────────────────

    def memory_profile(self, memory_id: str) -> dict:
        """
        PRD §4.2 — Build quality profile for a single memory.

        Returns usage_count, adoption_rate, success_rate, quality_score, status.
        """
        return self._profile_builder.build(memory_id)

    def memory_profiles_batch(self, memory_ids: List[str]) -> List[dict]:
        """Build profiles for multiple memories."""
        return self._profile_builder.build_batch(memory_ids)

    def top_memories(self, n: int = 10, min_usage: int = 1) -> List[dict]:
        """Return top-N highest quality memory profiles."""
        return self._profile_builder.build_top(n=n, min_usage=min_usage)

    def noisy_memories(self, min_noise: int = 3) -> List[dict]:
        """Return profiles for high-noise memories (suppression candidates)."""
        return self._profile_builder.build_noisy(min_noise=min_noise)

    # ── §4.3 Impact Metrics ────────────────────────────────────────────────────

    def impact_metrics(self) -> dict:
        """
        PRD §4.3 — Build system-wide impact metrics for Inspector header.

        Returns total_memories, memories_recalled, workflows_reused,
        tasks_avoided, tokens_saved, avg_quality_score, promoted/suppressed counts.
        """
        return self._metrics_builder.build()

    def impact_metrics_window(self, since_ts: float,
                               until_ts: float = None) -> dict:
        """Build metrics for a specific time window."""
        return self._metrics_builder.build_window(since_ts, until_ts)

    # ── §4.4 Timeline ─────────────────────────────────────────────────────────

    def timeline(self, task_id: str = None, memory_id: str = None,
                  limit: int = 100) -> list:
        """
        PRD §4.4 — Build chronological event stream.

        Provide task_id for task timeline, memory_id for memory timeline,
        or neither for the global recent timeline.
        """
        if task_id:
            return self._timeline_builder.build_for_task(task_id)
        elif memory_id:
            return self._timeline_builder.build_for_memory(memory_id, limit=limit)
        else:
            return self._timeline_builder.build_global(limit=limit)

    # ── Convenience: full Inspector snapshot ──────────────────────────────────

    def inspector_snapshot(self, task_id: str = None) -> dict:
        """
        Return a full Inspector-ready snapshot combining all 4 outputs.

        Useful for CLI / summary display.
        """
        snap = {
            "metrics": self.impact_metrics(),
        }
        if task_id:
            snap["task_trace"] = self.task_trace(task_id)
            snap["timeline"] = self.timeline(task_id=task_id)
        else:
            snap["timeline"] = self.timeline(limit=20)
        snap["top_memories"] = self.top_memories(n=5)
        return snap
