import logging
import random
import time

from colorama import Fore

logger = logging.getLogger(__name__)


class DopamineEngine:
    """
    Simulation of human neurochemistry.
    Manages boredom levels and interest-based interaction pacing.
    """

    def __init__(self):
        self.boredom = 0.0  # 0.0 to 100.0
        self.spike_threshold = 7.0
        self.homeostasis_rate = 0.05  # decay per minute
        self.last_spike = time.time()
        self.session_start = time.time()
        self.session_limit_seconds = random.uniform(10 * 60, 35 * 60)  # 10-35 mins session

    def process_content(self, classification: dict):
        """
        classification: {'quality': 'high'|'low', 'type': 'meme'|'aesthetic'|'ad', 'score': 0-10}
        """
        score = classification.get("score", 5.0)
        quality = classification.get("quality", "medium")

        # Calculate spike
        spike = score * 1.5 if quality == "high" else score * 0.5

        # Update boredom: negative correlation with high quality content
        if spike > self.spike_threshold:
            self.boredom = max(0.0, self.boredom - (spike * 0.2))
            logger.info(
                f"💉 [Dopamine] Spike detected! Interest high. Boredom decreased to {self.boredom:.1f}%",
                extra={"color": f"{Fore.YELLOW}"},
            )
        else:
            self.boredom = min(100.0, self.boredom + 5.0)
            logger.info(
                f"💉 [Dopamine] Low interest content. Boredom increased to {self.boredom:.1f}%",
                extra={"color": f"{Fore.YELLOW}"},
            )

        self.last_spike = time.time()
        return self.is_bored()

    def is_bored(self):
        return self.boredom >= 100.0

    def wants_to_doomscroll(self):
        # Engage fast swiping if highly bored but not fully exhausted
        # Make the behavior probabilistic so we don't get stuck in an infinite loop
        if 75.0 < self.boredom < 100.0:
            chance = (self.boredom - 70.0) / 30.0  # Scales from ~16% to 100% chance
            if random.random() < chance:
                # Decrease boredom slightly so the agent slowly snaps out of it
                self.boredom = max(70.0, self.boredom - 1.5)
                return True
        return False

    def wants_to_change_feed(self):
        # Engage context shift if highly bored
        if 80.0 < self.boredom < 100.0:
            return random.random() < 0.4
        return False

    def reset_boredom(self, decay=0.2):
        """
        Resets boredom after a successful context shift.
        We don't reset to 0.0 to prevent infinite looping in the same feeds.
        """
        old = self.boredom
        self.boredom = max(0.0, self.boredom * decay)
        logger.info(
            f"💉 [Dopamine] Context shifted. Boredom cooled: {old:.1f}% -> {self.boredom:.1f}%",
            extra={"color": f"{Fore.YELLOW}"},
        )

    def reset_session(self):
        """
        Resets all variables for a completely new app session.
        """
        self.boredom = 0.0
        self.session_start = time.time()
        self.last_spike = time.time()
        self.session_limit_seconds = random.uniform(10 * 60, 35 * 60)
        logger.info(
            "💉 [Dopamine] Session limits and neurochemistry reset to baseline.", extra={"color": f"{Fore.YELLOW}"}
        )

    def is_app_session_over(self):
        # Global Hard Kill check
        if getattr(self, "global_max_runtime_minutes", None):
            if hasattr(self, "global_start_time"):
                from datetime import datetime, timedelta

                if datetime.now() - self.global_start_time > timedelta(minutes=self.global_max_runtime_minutes):
                    logger.info(
                        f"🛑 [Timeout] Maximum runtime of {self.global_max_runtime_minutes} minutes reached (checked by DopamineEngine). Force-stopping session.",
                        extra={"color": f"{Fore.RED}"},
                    )
                    return True

        # True if we have scrolled too long or hit absolute burnout
        return (time.time() - self.session_start) > self.session_limit_seconds or self.boredom >= 100.0

    def get_pacing_modifier(self, base_score: float):
        """
        Returns a multiplier for sleep durations.
        High dopamine (high interest) = longer viewing time.
        """
        if base_score > 8:
            return random.uniform(2.0, 4.0)  # Entranced
        if base_score < 3:
            return random.uniform(0.1, 0.4)  # Fast-swipe
        return 1.0

    def decay(self):
        """
        Called periodically to return to baseline.
        """
        now = time.time()
        minutes = (now - self.last_spike) / 60.0
        self.boredom = min(100.0, self.boredom + (minutes * self.homeostasis_rate))
        self.last_spike = now
