"""Quality scorer — scores memory content richness and returns improvement hints.

Soft gate: always allows storage, never rejects. Returns a 0-10 score
and actionable hints so agents/users can improve memory quality.
"""

from __future__ import annotations

import re
from dataclasses import dataclass, field

# -- Cognitive richness word lists ------------------------------------------

_CAUSAL_PATTERN = re.compile(
    r"\b(because|caused|due to|led to|resulted in|reason|since|therefore"
    r"|so that|in order to|as a result|consequently)\b",
    re.IGNORECASE,
)

_TEMPORAL_PATTERN = re.compile(
    r"\b(after|before|then|when|while|during|until|once|first|next"
    r"|previously|subsequently|earlier|later|following)\b",
    re.IGNORECASE,
)

_COMPARATIVE_PATTERN = re.compile(
    r"\b(over|instead of|replaced|vs|versus|compared to|rather than"
    r"|better than|worse than|faster|slower|cheaper|preferred)\b",
    re.IGNORECASE,
)

# -- Quality thresholds -----------------------------------------------------

_MIN_CONTENT_LENGTH = 10
_LOW_THRESHOLD = 4
_HIGH_THRESHOLD = 7


@dataclass(frozen=True)
class QualityResult:
    """Quality assessment for a memory."""

    score: int  # 0-10
    quality: str  # "low" | "medium" | "high"
    hints: tuple[str, ...] = field(default_factory=tuple)

    def to_dict(self) -> dict[str, object]:
        result: dict[str, object] = {
            "quality": self.quality,
            "score": self.score,
        }
        if self.hints:
            result["hints"] = list(self.hints)
        return result


def score_memory(
    content: str,
    *,
    memory_type: str | None = None,
    tags: list[str] | None = None,
    context: dict[str, object] | None = None,
) -> QualityResult:
    """Score memory content quality on a 0-10 scale.

    Scoring breakdown:
    - Content length (0-2): >=10 chars +1, >=50 chars +1
    - Context dict provided (+3)
    - Tags provided, at least 1 (+1)
    - Non-default type provided (+1)
    - Cognitive richness (0-3): causal +1, temporal +1, comparative +1

    Args:
        content: The memory content text.
        memory_type: Memory type string (e.g. "decision", "fact").
        tags: List of tags.
        context: Structured context dict from agent.

    Returns:
        QualityResult with score, quality label, and improvement hints.
    """
    points = 0
    hints: list[str] = []

    # 1. Content length (0-2 points)
    content_len = len(content.strip())
    if content_len >= _MIN_CONTENT_LENGTH:
        points += 1
    else:
        hints.append(
            f"Content is very short ({content_len} chars) — add more detail for better recall"
        )
    if content_len >= 50:
        points += 1

    # 2. Context dict (+3 points)
    if context and len(context) > 0:
        points += 3
    else:
        hints.append("Add context dict (reason, alternatives, cause) for richer neural connections")

    # 3. Tags (+1 point)
    if tags and len(tags) > 0:
        points += 1
    else:
        hints.append("Add tags for better retrieval")

    # 4. Non-default type (+1 point)
    if memory_type and memory_type != "fact":
        points += 1
    elif not memory_type:
        hints.append("Specify memory type (decision, insight, error, workflow)")

    # 5. Cognitive richness (0-3 points)
    has_causal = bool(_CAUSAL_PATTERN.search(content))
    has_temporal = bool(_TEMPORAL_PATTERN.search(content))
    has_comparative = bool(_COMPARATIVE_PATTERN.search(content))

    if has_causal:
        points += 1
    if has_temporal:
        points += 1
    if has_comparative:
        points += 1

    cognitive_count = sum([has_causal, has_temporal, has_comparative])
    if cognitive_count == 0:
        hints.append(
            "Add reasoning: why (because...), when (after...), or comparison (over X, instead of Y)"
        )

    # Cap at 10
    points = min(points, 10)

    # Determine quality label
    if points >= _HIGH_THRESHOLD:
        quality = "high"
    elif points >= _LOW_THRESHOLD:
        quality = "medium"
    else:
        quality = "low"

    # Don't return hints for high quality
    if quality == "high":
        hints = []

    return QualityResult(
        score=points,
        quality=quality,
        hints=tuple(hints),
    )
