"""
ImportanceScorer

Composite importance scoring combining frequency, recency, emotion, and impact.
"""

from enum import Enum
from typing import TYPE_CHECKING

from app.services.memory.frequency_tracker import FrequencyTracker
from app.services.memory.emotion_analyzer import EmotionAnalyzer
from app.services.memory.impact_evaluator import ImpactEvaluator

if TYPE_CHECKING:
    from app.models.memory import UserMemory


class ImportanceLevel(str, Enum):
    """Importance level classification"""

    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


class ImportanceScorer:
    """Calculate composite importance score for memories

    Score formula:
        frequency_score * 0.35 +
        recency_score * 0.20 +
        emotion_score * 0.25 +
        impact_score * 0.20
    """

    # Score weights
    WEIGHT_FREQUENCY = 0.35
    WEIGHT_RECENCY = 0.20
    WEIGHT_EMOTION = 0.25
    WEIGHT_IMPACT = 0.20

    # Escalation threshold
    HIGH_THRESHOLD = 0.8
    MEDIUM_THRESHOLD = 0.5
    LOW_THRESHOLD = 0.0

    def __init__(self):
        self.tracker = FrequencyTracker()
        self.emotion_analyzer = EmotionAnalyzer()
        self.impact_evaluator = ImpactEvaluator()

    def calculate_score(self, memory: "UserMemory") -> float:
        """Calculate composite importance score (0.0 - 1.0)"""
        frequency = self.tracker.get_frequency_score(memory) * self.WEIGHT_FREQUENCY
        recency = self.tracker.get_recency_score(memory) * self.WEIGHT_RECENCY
        emotion = self.emotion_analyzer.calculate_score(memory) * self.WEIGHT_EMOTION
        impact = self.impact_evaluator.evaluate(memory) * self.WEIGHT_IMPACT

        total = frequency + recency + emotion + impact
        return round(min(1.0, max(0.0, total)), 3)

    def get_importance_level(self, score: float) -> ImportanceLevel:
        """Classify importance score into level"""
        if score >= self.HIGH_THRESHOLD:
            return ImportanceLevel.HIGH
        elif score >= self.MEDIUM_THRESHOLD:
            return ImportanceLevel.MEDIUM
        else:
            return ImportanceLevel.LOW

    def should_escalate(self, memory: "UserMemory") -> bool:
        """Check if a memory should be escalated (promoted to higher importance)

        A memory should escalate if:
        - Score exceeds HIGH_THRESHOLD
        - Emotion analysis shows high intensity keywords
        """
        score = self.calculate_score(memory)
        if score >= self.HIGH_THRESHOLD:
            return True

        # Check emotion intensity
        emotion_score = self.emotion_analyzer.calculate_score(memory)
        if emotion_score >= 0.9:
            return True

        return False

    def score_and_classify(self, memory: "UserMemory") -> tuple[float, ImportanceLevel]:
        """Calculate score and classify in one call"""
        score = self.calculate_score(memory)
        level = self.get_importance_level(score)
        return score, level

    def update_memory_importance(self, memory: "UserMemory") -> "UserMemory":
        """Update memory's importance_score and importance_level fields

        Returns the updated memory.
        """
        score, level = self.score_and_classify(memory)
        memory.importance_score = score
        memory.importance_level = level.value if isinstance(level, ImportanceLevel) else level
        return memory
