"""Background compression / summarisation engine for LociDB.

Compresses older raw memories into higher summary levels:
  0 → raw individual memories
  1 → daily digests
  2 → weekly digests
  3 → distilled knowledge

v0.1 implements a simple extractive approach — concatenate and truncate.
Future versions will plug in LLM-based abstractive summarisation.
"""

from __future__ import annotations

from datetime import datetime, timedelta, timezone
from typing import List, Optional

from .node import MemoryNode
from .store import MemoryStore


def _simple_summarize(contents: List[str], max_chars: int = 1000) -> str:
    """Very basic extractive summary: join and truncate."""
    joined = " | ".join(contents)
    if len(joined) <= max_chars:
        return joined
    return joined[:max_chars] + "…"


def _merge_entity_tags(nodes: List[MemoryNode]) -> List[str]:
    """Collect unique entity tags across a set of nodes."""
    tags: set[str] = set()
    for n in nodes:
        tags.update(n.entity_tags)
    return sorted(tags)


def compress_daily(
    store: MemoryStore,
    scope: Optional[str] = None,
    older_than_days: int = 2,
    dry_run: bool = False,
) -> List[MemoryNode]:
    """Compress raw (level-0) memories older than *older_than_days* into daily summaries.

    Returns the list of newly created summary nodes.
    """
    cutoff = datetime.now(timezone.utc) - timedelta(days=older_than_days)
    raw_nodes = store.list_nodes(scope=scope, summary_level=0, limit=10000)

    # Group by date
    by_date: dict[str, List[MemoryNode]] = {}
    for node in raw_nodes:
        ts = node.timestamp
        if ts.tzinfo is None:
            ts = ts.replace(tzinfo=timezone.utc)
        if ts >= cutoff:
            continue
        day_key = ts.strftime("%Y-%m-%d")
        by_date.setdefault(day_key, []).append(node)

    created: List[MemoryNode] = []
    for day_key, nodes in by_date.items():
        if len(nodes) < 2:
            continue
        summary_text = _simple_summarize([n.content for n in nodes])
        avg_importance = sum(n.importance for n in nodes) / len(nodes)

        summary_node = MemoryNode(
            content=f"[Daily summary {day_key}] {summary_text}",
            importance=min(avg_importance + 0.1, 1.0),
            entity_tags=_merge_entity_tags(nodes),
            context_scope=nodes[0].context_scope,
            summary_level=1,
        )

        if not dry_run:
            store.save_node(summary_node)
            for n in nodes:
                store.delete_node(n.id)

        created.append(summary_node)

    return created
