import logging
import random
from datetime import datetime

from colorama import Fore

from GramAddict.core.qdrant_memory import PersonaMemoryDB

logger = logging.getLogger(__name__)


class GrowthBrain:
    """
    Biological Feedback and Persona Management.

    Two critical functions:
    1. Circadian Rhythm — modulates ALL sleep/dwell times based on time of day
    2. Persona Refinement — learns from interaction outcomes and stores insights
    """

    def __init__(self, username: str, persona_interests: list[str] = None):
        self.username = username
        self.persona_memory = PersonaMemoryDB()
        self.persona_interests = persona_interests or []
        self.strategy = "aggressive_growth"  # Will be updated by orchestrator
        self.last_learning_at = datetime.now()

    def evaluate_governance(self, dopamine_engine, job_target: str, is_reels: bool = False) -> str:
        """
        Global Strategy Oracle.
        Decides if the bot should stay in the current feed, check curiosity targets,
        or escape due to boredom.

        Returns: "STAY", "SHIFT_CONTEXT", "CHECK_CURIOSITY"
        """
        # 1. Boredom Check (Priority 1)
        if dopamine_engine.boredom > 85.0 and random.random() < 0.2:
            logger.info(
                "🧠 [GrowthBrain] Supreme boredom reached or periodic shift triggered. Decision: SHIFT_CONTEXT."
            )
            return "SHIFT_CONTEXT"

        # 2. Curiosity Check (Priority 2)
        # Only in main feeds, not during deep reels sessions
        if job_target.lower() in ("homefeed", "feed", "home") and not is_reels:
            if random.random() < 0.06:
                logger.info("🧠 [GrowthBrain] Spontaneous curiosity spike. Decision: CHECK_CURIOSITY.")
                return "CHECK_CURIOSITY"

        return "STAY"

    def get_current_desire(self, dopamine_engine, available_targets=None) -> str:
        """
        Agent Core: Determines what the bot actually WANTS to do right now,
        based on strategy, circadian rhythm, and dopamine/boredom levels.

        Returns a high-level semantic Desire string.
        """
        if dopamine_engine.boredom > 80.0:
            logger.info("🧠 [GrowthBrain] Internal drive: Context shift required.")
            return "ShiftContext"

        weights = {}
        if self.strategy == "aggressive_growth":
            weights = {
                "DiscoverNewContent": 60,  # Explore, Reels
                "NurtureCommunity": 15,  # HomeFeed
                "SocialReciprocity": 25,  # Follow list, DMs
            }
        elif self.strategy == "community_builder":
            weights = {
                "DiscoverNewContent": 20,
                "NurtureCommunity": 50,
                "SocialReciprocity": 30,
            }
        elif self.strategy == "passive_learning":
            weights = {
                "DiscoverNewContent": 80,  # Maximize exploration to build Vector DB
                "NurtureCommunity": 20,
                "SocialReciprocity": 0,
            }
        else:  # stealth_lurker
            weights = {
                "DiscoverNewContent": 40,
                "NurtureCommunity": 50,
                "SocialReciprocity": 10,
            }

        choices = []
        for desire, weight in weights.items():
            choices.extend([desire] * weight)

        selected_desire = random.choice(choices)
        logger.info(f"🧠 [GrowthBrain] Strategy '{self.strategy}' dictated Desire: {selected_desire}")
        return selected_desire

    def get_current_goal(self, dopamine_engine, available_goals: list[str], success_rates: dict = None) -> str:
        """
        Autonomously selects the next strategic goal.
        If no goals are configured, falls back to legacy desires.
        Weights goals based on session success rates if provided.

        .. deprecated::
            Use select_task() instead for concrete, plugin-linked task selection.
        """
        import random

        if not available_goals:
            # Legacy Desire Mapping (Fallback)
            return self.get_current_desire(dopamine_engine)

        if dopamine_engine.boredom > 80:
            return "ShiftContext"  # High boredom triggers a context shift

        if not success_rates:
            return random.choice(available_goals)

        weights = []
        for goal in available_goals:
            base_weight = 1.0
            success_count = success_rates.get(goal, 0)
            weight = base_weight + float(success_count)
            weights.append(weight)

        return random.choices(available_goals, weights=weights, k=1)[0]

    def select_task(self, dopamine_engine, available_tasks: list) -> "Optional[Task]":
        """Select the next concrete Task using weighted random selection.

        This is the primary interface for the orchestrator. Unlike get_current_goal()
        which returns abstract strings, this returns a Task object with a specific
        target_screen, budget, and success metric.

        Returns:
            Task: The selected task to execute.
            None: If no tasks available or boredom is too high (ShiftContext signal).
        """
        if not available_tasks:
            return None

        # High boredom = ShiftContext (take a break, switch feed)
        if dopamine_engine.boredom > 85.0:
            logger.info("🧠 [GrowthBrain] Boredom too high for task selection. ShiftContext.")
            return None

        weights = [task.weight for task in available_tasks]
        selected = random.choices(available_tasks, weights=weights, k=1)[0]
        logger.info(
            f"🧠 [GrowthBrain] Selected task: {selected.verb} → {selected.target_screen} "
            f"(weight={selected.weight:.2f}, budget={selected.budget_posts})"
        )
        return selected

    def get_circadian_pacing(self) -> float:
        """
        Adjusts activity levels based on the current local time
        to simulate human sleep/wake cycles.

        Returns a multiplier (0.1 to 1.0) that should be applied to ALL sleep durations.
        Lower = slower (more human-like during off-hours).
        """
        hour = datetime.now().hour

        # Determine current pacing state
        if 2 <= hour <= 5:
            pacing = 0.1
            state_id = "deep_sleep"
            msg = "🧠 [GrowthBrain] Deep sleep mode. Performance 10%."
        elif 6 <= hour <= 7:
            pacing = 0.4
            state_id = "waking_up"
            msg = "🧠 [GrowthBrain] Waking up slowly. Performance 40%."
        elif 8 <= hour <= 9:
            pacing = 0.7
            state_id = "morning_warmup"
            msg = "🧠 [GrowthBrain] Morning warmup. Performance 70%."
        elif hour >= 23 or hour <= 1:
            pacing = 0.5
            state_id = "evening_winddown"
            msg = "🧠 [GrowthBrain] Evening wind-down. Performance 50%."
        else:
            pacing = 1.0
            state_id = "peak_hours"
            msg = "🧠 [GrowthBrain] Peak metabolic rate. Performance 100%."

        # Log intelligently (only info log on state change)
        if not hasattr(self, "_last_pacing_state") or getattr(self, "_last_pacing_state") != state_id:
            logger.info(msg, extra={"color": f"{Fore.GREEN}"})
            self._last_pacing_state = state_id
        else:
            logger.debug(msg)

        return pacing

    def refine_persona(self, interaction_outcomes: list[dict]):
        """
        Learns from interaction outcomes to refine persona understanding.

        interaction_outcomes: [{'username': str, 'action': 'like'|'comment'|'skip', 'resonance': float}]

        Stores high-performing interaction patterns in PersonaMemoryDB.
        """
        if not interaction_outcomes:
            return

        # Find interactions that had high resonance (those are our niche)
        high_res = [o for o in interaction_outcomes if o.get("resonance", 0) > 0.7]
        low_res = [o for o in interaction_outcomes if o.get("resonance", 0) < 0.3]

        if high_res:
            insight = f"High-resonance interactions in this session: {len(high_res)} posts matched niche."
            self.persona_memory.store_persona_insight("session_learning", insight)
            logger.info(
                f"🧠 [GrowthBrain] Session learning: {len(high_res)} high-resonance, {len(low_res)} low-resonance posts.",
                extra={"color": f"{Fore.GREEN}"},
            )

        self.last_learning_at = datetime.now()

    def get_persona_context(self) -> str:
        """Returns learned persona context for LLM prompts."""
        base = ""
        if self.persona_interests:
            base = f"Core interests: {', '.join(self.persona_interests)}"

        learned = self.persona_memory.get_persona_context()
        if learned:
            return f"{base}\n{learned}" if base else learned
        return base

    # ── [Phase 3] Humanized Decision Logic ──

    def wants_to_double_tap(self, is_reel: bool = False) -> bool:
        """Determines if the bot should use double-tap for likes."""
        prob = 0.45 if self.strategy == "aggressive_growth" else 0.25
        if is_reel:
            prob += 0.20  # People double-tap reels more often
        return random.random() < prob

    def evaluate_hesitation(self) -> bool:
        """Simulates human 'change of mind' or hesitation before a major action."""
        # Stealthy or passive bots hesitate more
        prob = 0.15 if self.strategy in ("stealth_lurker", "passive_learning") else 0.05
        return random.random() < prob

    def wants_to_repost(self, resonance_score: float) -> bool:
        """Decides if content is worthy of a repost."""
        if resonance_score < 0.85:
            return False
        prob = 0.3 if self.strategy == "aggressive_growth" else 0.1
        return random.random() < prob
