"""Importance scoring engine for LociDB.

Computes a composite importance score from recency, entity relevance,
and usage frequency.
"""

from __future__ import annotations

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

from .node import MemoryNode


# Default decay rate: memory half-life ≈ 14 days
DEFAULT_DECAY_RATE = 0.05


def compute_importance(
    node: MemoryNode,
    query_entities: Optional[List[str]] = None,
    decay_rate: float = DEFAULT_DECAY_RATE,
    now: Optional[datetime] = None,
) -> float:
    """Compute an importance score in [0, 1] for a memory node.

    Formula:
        importance = 0.4 * recency + 0.4 * entity_relevance + 0.2 * usage_frequency

    Where:
        recency          = exp(-decay_rate * days_since_created)
        entity_relevance = |overlap(node.entity_tags, query_entities)| / max(|query_entities|, 1)
        usage_frequency  = min(node.access_count / 10, 1.0)
    """
    if now is None:
        now = datetime.now(timezone.utc)

    # Ensure both datetimes are tz-aware for subtraction
    ts = node.timestamp
    if ts.tzinfo is None:
        ts = ts.replace(tzinfo=timezone.utc)
    if now.tzinfo is None:
        now = now.replace(tzinfo=timezone.utc)

    days_since = max((now - ts).total_seconds() / 86400, 0)
    recency = math.exp(-decay_rate * days_since)

    if query_entities:
        overlap = set(node.entity_tags).intersection(query_entities)
        entity_relevance = len(overlap) / max(len(query_entities), 1)
    else:
        entity_relevance = 0.0

    usage_frequency = min(node.access_count / 10.0, 1.0)

    return 0.4 * recency + 0.4 * entity_relevance + 0.2 * usage_frequency


def batch_score(
    nodes: List[MemoryNode],
    query_entities: Optional[List[str]] = None,
    decay_rate: float = DEFAULT_DECAY_RATE,
) -> List[float]:
    """Score a list of nodes and return corresponding importance values."""
    now = datetime.now(timezone.utc)
    return [
        compute_importance(n, query_entities, decay_rate, now)
        for n in nodes
    ]
