#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Emotional Valence System (Phase 4+ AGI, 9/10 panels CRITICAL).

Two-dimensional affect model:
  - valence: -1.0 (negative) to +1.0 (positive)
  - arousal: 0.0 (calm) to 1.0 (intense)

Valence gates temporal decay (emotional memories persist longer)
and boosts retrieval salience (negativity bias for safety).
"""

_POSITIVE = frozenset({
    "solved", "success", "fixed", "shipped", "improved", "working",
    "passed", "resolved", "completed", "achieved", "optimized",
    "implemented", "deployed", "merged", "verified", "stable",
})

_NEGATIVE = frozenset({
    "failed", "broken", "crash", "bug", "error", "lost", "killed",
    "regression", "corrupted", "timeout", "deadlock", "rejected",
    "violated", "missing", "stale", "orphan", "zombie", "leaked",
})


def compute_valence(text: str) -> tuple[float, float]:
    """Compute (valence, arousal) from text content.

    valence: -1.0 to +1.0 (sign of emotional content)
    arousal: 0.0 to 1.0 (intensity, reuses emotional_intensity logic)
    """
    if not text:
        return (0.0, 0.0)

    words = set(text.lower().split())
    pos = len(words & _POSITIVE)
    neg = len(words & _NEGATIVE)
    total = pos + neg

    if total == 0:
        valence = 0.0
    else:
        valence = round((pos - neg) / total, 3)

    # Arousal: caps/punctuation density + keyword count
    caps_ratio = sum(1 for c in text if c.isupper()) / max(len(text), 1)
    punct_ratio = sum(1 for c in text if c in "!?") / max(len(text), 1)
    keyword_density = min(1.0, total / max(len(words), 1) * 5)
    arousal = round(min(1.0, caps_ratio * 3 + punct_ratio * 10 + keyword_density * 0.5), 3)

    return (valence, arousal)


def get_valence_half_life_multiplier(valence: float = 0.0,
                                      arousal: float = 0.0) -> float:
    """High-arousal emotional memories persist longer (1.0x-1.5x half-life).

    Based on McGaugh (2004): emotional arousal enhances memory consolidation.
    Only arousal (not valence sign) modulates persistence.
    """
    if arousal > 0.5:
        return 1.0 + (arousal - 0.5) * 1.0  # 1.0x at 0.5, 1.5x at 1.0
    return 1.0
