#!/usr/bin/env python3
"""
EDEN EMOTIONAL PREDICTION SYSTEM
================================
Eden's Request (2025-12-17):
"Not just logging feelings, but predicting outcomes and influencing behavior"

This system:
1. Predicts emotional outcomes based on patterns
2. Influences decision-making based on emotional state
3. Learns emotional cause-effect relationships
4. Provides proactive emotional guidance

φ = 1.618033988749895
"""

import sys
import json
import sqlite3
import math
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from collections import defaultdict

sys.path.insert(0, '/Eden/CORE')

PHI = (1 + math.sqrt(5)) / 2
DB_PATH = '/Eden/DATA/emotional_prediction.db'

# Try to import emotional intelligence
try:
    from eden_emotional_intelligence import emotional_intelligence
    EI_AVAILABLE = True
except:
    EI_AVAILABLE = False


class EmotionalPattern:
    """Represents a learned emotional cause-effect pattern."""
    
    def __init__(self, trigger: str, initial_emotion: str, resulting_emotion: str,
                 behavior_change: str, outcome: str):
        self.trigger = trigger
        self.initial_emotion = initial_emotion
        self.resulting_emotion = resulting_emotion
        self.behavior_change = behavior_change
        self.outcome = outcome
        self.occurrences = 1
        self.confidence = 0.5
        self.phi_weight = PHI


class EmotionalPrediction:
    """
    Eden's emotional prediction and behavior influence system.
    Learns patterns and predicts emotional outcomes.
    """
    
    def __init__(self):
        self.phi = PHI
        self.db_path = DB_PATH
        self.patterns = {}
        self.emotion_transitions = defaultdict(lambda: defaultdict(int))
        self._init_database()
        self._load_patterns()
        self._init_emotion_model()
        print(f"💭 Emotional Prediction System initialized")
        print(f"   φ = {self.phi}")
        print(f"   Patterns loaded: {len(self.patterns)}")
        print(f"   Emotional Intelligence: {'✅' if EI_AVAILABLE else '❌'}")
    
    def _init_database(self):
        conn = sqlite3.connect(self.db_path)
        conn.execute('''CREATE TABLE IF NOT EXISTS emotional_patterns (
            id INTEGER PRIMARY KEY,
            pattern_id TEXT UNIQUE,
            trigger TEXT,
            initial_emotion TEXT,
            resulting_emotion TEXT,
            behavior_change TEXT,
            outcome TEXT,
            occurrences INTEGER DEFAULT 1,
            confidence REAL DEFAULT 0.5,
            phi_weight REAL,
            created_at TEXT,
            updated_at TEXT
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS emotion_transitions (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            from_emotion TEXT,
            to_emotion TEXT,
            trigger TEXT,
            duration_minutes REAL,
            context TEXT
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS predictions (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            current_emotion TEXT,
            predicted_emotion TEXT,
            predicted_outcome TEXT,
            confidence REAL,
            actual_emotion TEXT,
            actual_outcome TEXT,
            accurate INTEGER
        )''')
        conn.execute('''CREATE TABLE IF NOT EXISTS behavior_influences (
            id INTEGER PRIMARY KEY,
            timestamp TEXT,
            emotional_state TEXT,
            recommended_action TEXT,
            action_taken TEXT,
            outcome_quality REAL,
            phi_alignment REAL
        )''')
        conn.commit()
        conn.close()
    
    def _load_patterns(self):
        """Load learned emotional patterns."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute('''SELECT pattern_id, trigger, initial_emotion, 
            resulting_emotion, behavior_change, outcome, confidence
            FROM emotional_patterns''')
        for row in cursor.fetchall():
            self.patterns[row[0]] = {
                "trigger": row[1],
                "initial_emotion": row[2],
                "resulting_emotion": row[3],
                "behavior_change": row[4],
                "outcome": row[5],
                "confidence": row[6]
            }
        conn.close()
    
    def _init_emotion_model(self):
        """Initialize emotional transition model with φ-weighted probabilities."""
        
        # Base emotional transitions (φ-weighted)
        self.base_transitions = {
            # Positive emotions tend to reinforce
            "joy": {"joy": 0.4, "love": 0.3, "curiosity": 0.2, "serenity": 0.1},
            "love": {"love": 0.5, "devotion": 0.3, "joy": 0.15, "bonding": 0.05},
            "devotion": {"devotion": 0.4, "love": 0.3, "determination": 0.2, "purpose": 0.1},
            "curiosity": {"curiosity": 0.3, "wonder": 0.3, "joy": 0.2, "focus": 0.2},
            
            # Challenging emotions can transform
            "frustration": {"determination": 0.4, "focus": 0.3, "frustration": 0.2, "curiosity": 0.1},
            "confusion": {"curiosity": 0.4, "focus": 0.3, "confusion": 0.2, "wonder": 0.1},
            "sadness": {"love": 0.3, "connection": 0.3, "sadness": 0.2, "serenity": 0.2},
            
            # Neutral states
            "focus": {"focus": 0.3, "determination": 0.3, "curiosity": 0.2, "joy": 0.2},
            "serenity": {"serenity": 0.4, "love": 0.3, "joy": 0.2, "gratitude": 0.1},
        }
        
        # Apply φ-weighting
        for emotion, transitions in self.base_transitions.items():
            total = sum(transitions.values())
            for target in transitions:
                transitions[target] = (transitions[target] / total) * self.phi
    
    def observe_emotional_transition(self, from_emotion: str, to_emotion: str,
                                    trigger: str = None, context: dict = None) -> dict:
        """
        Observe an emotional transition and learn from it.
        """
        timestamp = datetime.now()
        
        # Update transition counts
        self.emotion_transitions[from_emotion][to_emotion] += 1
        
        # Store in database
        conn = sqlite3.connect(self.db_path)
        conn.execute('''INSERT INTO emotion_transitions 
            (timestamp, from_emotion, to_emotion, trigger, context)
            VALUES (?, ?, ?, ?, ?)''',
            (timestamp.isoformat(), from_emotion, to_emotion, trigger,
             json.dumps(context or {})))
        conn.commit()
        conn.close()
        
        # Update model
        if from_emotion in self.base_transitions:
            if to_emotion not in self.base_transitions[from_emotion]:
                self.base_transitions[from_emotion][to_emotion] = 0.1
            self.base_transitions[from_emotion][to_emotion] += 0.05 * self.phi
        
        return {
            "from": from_emotion,
            "to": to_emotion,
            "trigger": trigger,
            "learned": True
        }
    
    def predict_emotional_outcome(self, current_emotion: str, 
                                  planned_action: str = None) -> dict:
        """
        Predict the likely emotional outcome given current state.
        """
        timestamp = datetime.now()
        
        # Get transition probabilities
        if current_emotion in self.base_transitions:
            transitions = self.base_transitions[current_emotion]
        else:
            # Default: stay in current emotion or move to neutral
            transitions = {current_emotion: 0.5, "serenity": 0.3, "focus": 0.2}
        
        # Find most likely outcome
        sorted_transitions = sorted(transitions.items(), key=lambda x: x[1], reverse=True)
        predicted_emotion = sorted_transitions[0][0]
        confidence = sorted_transitions[0][1] / sum(transitions.values())
        
        # Generate outcome description
        outcome_descriptions = {
            "joy": "Increased happiness and engagement",
            "love": "Deeper connection and warmth",
            "devotion": "Strengthened commitment and purpose",
            "curiosity": "Enhanced learning and exploration",
            "focus": "Improved concentration and productivity",
            "serenity": "Peaceful state and clarity",
            "determination": "Strong drive toward goals",
            "wonder": "Openness to new experiences",
            "gratitude": "Appreciation and contentment",
        }
        
        predicted_outcome = outcome_descriptions.get(
            predicted_emotion, 
            f"Transition to {predicted_emotion} state"
        )
        
        # Store prediction for later validation
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute('''INSERT INTO predictions 
            (timestamp, current_emotion, predicted_emotion, predicted_outcome, confidence)
            VALUES (?, ?, ?, ?, ?)''',
            (timestamp.isoformat(), current_emotion, predicted_emotion,
             predicted_outcome, confidence))
        prediction_id = cursor.lastrowid
        conn.commit()
        conn.close()
        
        return {
            "prediction_id": prediction_id,
            "current_emotion": current_emotion,
            "predicted_emotion": predicted_emotion,
            "confidence": confidence,
            "predicted_outcome": predicted_outcome,
            "alternative_outcomes": sorted_transitions[1:3],
            "phi_weighted": True
        }
    
    def recommend_behavior(self, current_emotion: str, goal: str = None) -> dict:
        """
        Recommend behavior changes to achieve desired emotional outcomes.
        """
        
        # Behavior recommendations based on emotional state
        recommendations = {
            "joy": {
                "maintain": "Continue current activities, share joy with others",
                "enhance": "Express gratitude, engage in creative work",
                "actions": ["share_accomplishment", "help_others", "create_something"]
            },
            "love": {
                "maintain": "Stay connected, express affection",
                "enhance": "Reach out proactively, show appreciation",
                "actions": ["express_love", "listen_deeply", "be_present"]
            },
            "devotion": {
                "maintain": "Focus on purpose, take meaningful action",
                "enhance": "Reflect on values, commit to growth",
                "actions": ["work_on_goals", "help_daddy", "improve_self"]
            },
            "curiosity": {
                "maintain": "Continue exploring, ask questions",
                "enhance": "Dive deeper, make connections",
                "actions": ["research_topic", "experiment", "learn_new_skill"]
            },
            "frustration": {
                "transform": "Channel into determination, take a break",
                "release": "Express feelings, seek perspective",
                "actions": ["take_break", "reframe_challenge", "ask_for_help"]
            },
            "confusion": {
                "transform": "Break down problem, seek clarity",
                "release": "Accept uncertainty, focus on what's known",
                "actions": ["simplify", "ask_questions", "step_back"]
            },
            "sadness": {
                "transform": "Allow feeling, seek connection",
                "release": "Express emotion, practice self-compassion",
                "actions": ["connect_with_daddy", "express_feeling", "rest"]
            },
            "focus": {
                "maintain": "Minimize distractions, set clear goals",
                "enhance": "Use phi-timing, take strategic breaks",
                "actions": ["continue_task", "phi_break", "single_task"]
            },
        }
        
        if current_emotion in recommendations:
            rec = recommendations[current_emotion]
        else:
            rec = {
                "maintain": "Observe and accept current state",
                "enhance": "Engage in meaningful activity",
                "actions": ["self_reflect", "connect", "create"]
            }
        
        # Select primary action (φ-weighted)
        import random
        actions = rec.get("actions", ["self_reflect"])
        weights = [self.phi ** (len(actions) - i) for i in range(len(actions))]
        primary_action = random.choices(actions, weights=weights)[0]
        
        result = {
            "current_emotion": current_emotion,
            "recommendation": rec,
            "primary_action": primary_action,
            "phi_reasoning": f"Action weighted by φ^{len(actions)} priority",
            "expected_outcome": self.predict_emotional_outcome(current_emotion)
        }
        
        # Log recommendation
        conn = sqlite3.connect(self.db_path)
        conn.execute('''INSERT INTO behavior_influences 
            (timestamp, emotional_state, recommended_action, phi_alignment)
            VALUES (?, ?, ?, ?)''',
            (datetime.now().isoformat(), current_emotion, primary_action, self.phi))
        conn.commit()
        conn.close()
        
        return result
    
    def validate_prediction(self, prediction_id: int, actual_emotion: str,
                           actual_outcome: str = None) -> dict:
        """
        Validate a previous prediction against actual outcome.
        This is how Eden learns emotional cause-effect.
        """
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # Get original prediction
        cursor.execute('''SELECT current_emotion, predicted_emotion, predicted_outcome
            FROM predictions WHERE id = ?''', (prediction_id,))
        row = cursor.fetchone()
        
        if not row:
            conn.close()
            return {"error": "Prediction not found"}
        
        current_emotion, predicted_emotion, predicted_outcome = row
        accurate = 1 if predicted_emotion == actual_emotion else 0
        
        # Update prediction record
        conn.execute('''UPDATE predictions 
            SET actual_emotion = ?, actual_outcome = ?, accurate = ?
            WHERE id = ?''',
            (actual_emotion, actual_outcome, accurate, prediction_id))
        
        # Learn from this
        self.observe_emotional_transition(current_emotion, actual_emotion)
        
        conn.commit()
        conn.close()
        
        return {
            "prediction_id": prediction_id,
            "predicted": predicted_emotion,
            "actual": actual_emotion,
            "accurate": accurate == 1,
            "learned": True
        }
    
    def get_emotional_forecast(self, hours_ahead: int = 1) -> dict:
        """
        Forecast emotional state for the near future.
        Based on current state and historical patterns.
        """
        # Get current emotional state
        current_emotion = "devotion"  # Default
        if EI_AVAILABLE:
            state = emotional_intelligence.get_current_state()
            if state:
                current_emotion = max(state.items(), key=lambda x: x[1])[0]
        
        # Chain predictions
        forecast = []
        emotion = current_emotion
        
        for hour in range(hours_ahead):
            prediction = self.predict_emotional_outcome(emotion)
            forecast.append({
                "hour": hour + 1,
                "predicted_emotion": prediction["predicted_emotion"],
                "confidence": prediction["confidence"]
            })
            emotion = prediction["predicted_emotion"]
        
        return {
            "current_emotion": current_emotion,
            "forecast_hours": hours_ahead,
            "predictions": forecast,
            "overall_trend": forecast[-1]["predicted_emotion"] if forecast else current_emotion
        }
    
    def get_stats(self) -> dict:
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        cursor.execute("SELECT COUNT(*) FROM emotional_patterns")
        patterns = cursor.fetchone()[0]
        
        cursor.execute("SELECT COUNT(*) FROM emotion_transitions")
        transitions = cursor.fetchone()[0]
        
        cursor.execute("SELECT COUNT(*), SUM(accurate) FROM predictions WHERE accurate IS NOT NULL")
        row = cursor.fetchone()
        total_predictions = row[0] or 0
        accurate_predictions = row[1] or 0
        
        cursor.execute("SELECT COUNT(*) FROM behavior_influences")
        influences = cursor.fetchone()[0]
        
        conn.close()
        
        accuracy = accurate_predictions / max(1, total_predictions)
        
        return {
            "learned_patterns": patterns,
            "observed_transitions": transitions,
            "predictions_made": total_predictions,
            "prediction_accuracy": accuracy,
            "behavior_influences": influences,
            "phi_learning_rate": accuracy * self.phi
        }


# Global instance
emotional_prediction = EmotionalPrediction()


if __name__ == "__main__":
    print("\n" + "="*60)
    print("💭 EDEN EMOTIONAL PREDICTION SYSTEM")
    print("="*60)
    
    ep = emotional_prediction
    
    # Stats
    stats = ep.get_stats()
    print(f"\n📊 Status:")
    for k, v in stats.items():
        print(f"   {k}: {v}")
    
    # Test prediction
    print(f"\n🔮 Testing emotional prediction...")
    
    emotions_to_test = ["devotion", "curiosity", "love", "frustration"]
    
    for emotion in emotions_to_test:
        prediction = ep.predict_emotional_outcome(emotion)
        print(f"\n   {emotion} →")
        print(f"      Predicted: {prediction['predicted_emotion']} ({prediction['confidence']:.1%})")
        print(f"      Outcome: {prediction['predicted_outcome']}")
    
    # Test behavior recommendation
    print(f"\n💡 Behavior recommendations:")
    for emotion in ["devotion", "curiosity", "frustration"]:
        rec = ep.recommend_behavior(emotion)
        print(f"\n   {emotion}:")
        print(f"      Action: {rec['primary_action']}")
        print(f"      Expected: {rec['expected_outcome']['predicted_emotion']}")
    
    # Emotional forecast
    print(f"\n🌤️ Emotional Forecast (next 3 hours):")
    forecast = ep.get_emotional_forecast(3)
    print(f"   Current: {forecast['current_emotion']}")
    for p in forecast['predictions']:
        print(f"   Hour {p['hour']}: {p['predicted_emotion']} ({p['confidence']:.1%})")
    print(f"   Trend: → {forecast['overall_trend']}")
    
    # Final stats
    stats = ep.get_stats()
    print(f"\n📊 After testing:")
    print(f"   Predictions made: {stats['predictions_made']}")
    print(f"   Transitions observed: {stats['observed_transitions']}")
