"""AttitudeState — dynamic attitude of a character toward a user.

Extracted from app/services/chat_engine.py.
No sqlalchemy/fastapi/redis imports allowed.
"""
from __future__ import annotations

import time
from datetime import datetime, timezone


class AttitudeState:
    """
    Dynamic attitude state of a character toward a user.

    Not just an affection score, but a set of dimensions describing the
    current emotional state. Attitudes change in real-time based on events
    and conversations, and are injected into the system prompt to influence
    the character's responses.
    """

    def __init__(self, character_id: str, user_id: str):
        self.character_id = character_id
        self.user_id = user_id

        # -- Core dimensions --
        self.affection: int = 50         # 0-100
        self.trust: int = 50             # 0-100
        self.mood: str = "neutral"
        self.emotional_state: str = ""   # Detailed emotion description
        self.attitude_toward_user: str = ""  # Attitude description
        self.recent_shift: str = ""      # Reason for recent attitude shift

        # -- Event-triggered persistent modifiers --
        self.attitude_modifiers: list[dict] = []

        # -- History --
        self.history: list[dict] = []
        self.last_interaction_at: datetime | None = None
        self.cooldown_hint_needed: bool = False

    def apply_time_decay(self, now: datetime | None = None) -> bool:
        """Apply natural decay after inactivity."""
        if not self.last_interaction_at:
            return False

        now = now or datetime.now(timezone.utc)
        last = self.last_interaction_at
        if last.tzinfo is None:
            last = last.replace(tzinfo=timezone.utc)

        days_since = (now - last).days
        if days_since < 3:
            return False

        before_affection = self.affection
        before_trust = self.trust

        affection_decay = min(days_since * 0.5, max(0.0, self.affection - 30))
        trust_decay = min(days_since * 0.2, max(0.0, self.trust - 20))
        self.affection = max(30, int(round(self.affection - affection_decay)))
        self.trust = max(20, int(round(self.trust - trust_decay)))

        self.cooldown_hint_needed = self.affection != before_affection or self.trust != before_trust
        return self.cooldown_hint_needed

    def apply_event_impact(self, event_description: str, impact: dict):
        """Update attitude when a significant event occurs."""
        self.affection = max(0, min(100, self.affection + impact.get("affection_delta", 0)))
        self.trust = max(0, min(100, self.trust + impact.get("trust_delta", 0)))

        if "new_mood" in impact:
            self.mood = impact["new_mood"]

        if "attitude_shift" in impact:
            self.attitude_modifiers.append({
                "trigger": event_description,
                "effect": impact["attitude_shift"],
                "remaining": impact.get("duration", 5),
            })
            self.recent_shift = f"\u56e0\u70ba\u300c{event_description}\u300d\uff0c{impact['attitude_shift']}"

        self.history.append({
            "time": time.time(),
            "event": event_description,
            "impact": impact,
            "resulting_state": self.snapshot(),
        })

    def decay_modifiers(self):
        """Decay temporary attitude modifiers after each conversation turn."""
        active = []
        for mod in self.attitude_modifiers:
            mod["remaining"] -= 1
            if mod["remaining"] > 0:
                active.append(mod)
        self.attitude_modifiers = active

        if not self.attitude_modifiers:
            self.recent_shift = ""

    def snapshot(self) -> dict:
        return {
            "affection": self.affection,
            "trust": self.trust,
            "mood": self.mood,
            "emotional_state": self.emotional_state,
            "attitude_toward_user": self.attitude_toward_user,
            "active_modifiers": [m["effect"] for m in self.attitude_modifiers],
        }

    def to_prompt_section(self) -> str:
        """Generate attitude description for injection into system prompt."""
        lines = [
            f"\u597d\u611f\u5ea6\uff1a{self.affection}/100",
            f"\u4fe1\u4efb\u5ea6\uff1a{self.trust}/100",
            f"\u7576\u524d\u5fc3\u60c5\uff1a{self.mood}",
        ]

        if self.emotional_state:
            lines.append(f"\u60c5\u7dd2\u72c0\u614b\uff1a{self.emotional_state}")

        if self.attitude_toward_user:
            lines.append(f"\u5c0d\u7528\u6236\u7684\u614b\u5ea6\uff1a{self.attitude_toward_user}")

        if self.recent_shift:
            lines.append(f"\u26a1 \u6700\u8fd1\u7684\u614b\u5ea6\u8b8a\u5316\uff1a{self.recent_shift}")

        if self.attitude_modifiers:
            effects = "\uff1b".join(m["effect"] for m in self.attitude_modifiers)
            lines.append(f"\u7576\u524d\u53d7\u5230\u7684\u5f71\u97ff\uff1a{effects}")

        return "\n".join(lines)
