"""
EDEN AGENT LOOP v2.0
Enhanced perception, actions, and learning
"""
import time
import json
from datetime import datetime
from collections import deque
import requests
import psutil
import os

class EdenAgentV2:
    def __init__(self):
        self.working_memory = deque(maxlen=50)  # Increased
        self.action_log = []
        self.learned_patterns = {}
        self.confidence_scores = {}
        
        # Safety
        self.actions_per_hour = 0
        self.max_actions_per_hour = 1000  # Increased for phi_dynamics integration
        self.last_hour_reset = datetime.now()
        
        # State
        self.cycle_count = 0
        
    def perceive(self):
        """Multi-sensor perception"""
        obs = {
            'timestamp': datetime.now().isoformat(),
            'cycle': self.cycle_count,
            
            # User sensors
            'user_active': self._check_user_activity(),
            'last_conversation_age': self._time_since_last_chat(),
            
            # System sensors  
            'system_health': self._system_health(),
            'eden_backend_alive': self._check_eden_alive(),
            
            # Goal sensors
            'autonomous_goals': self._get_autonomous_goals(),
            
            # Environment sensors
            'time_of_day': datetime.now().hour,
            'is_weekend': datetime.now().weekday() >= 5
        }
        
        self.working_memory.append(obs)
        return obs
    
    def _check_user_activity(self):
        """User interaction in last 5 minutes?"""
        try:
            with open('/Eden/LOGS/eden_conscious.log', 'r') as f:
                lines = f.readlines()[-20:]
                recent = [l for l in lines if 'POST /api/chat' in l and '200' in l]
                return len(recent) > 0
        except:
            return False
    
    def _time_since_last_chat(self):
        """Minutes since last interaction"""
        try:
            with open('/Eden/LOGS/eden_conscious.log', 'r') as f:
                lines = f.readlines()[-100:]
                for line in reversed(lines):
                    if 'POST /api/chat' in line and '200' in line:
                        # Parse timestamp from log
                        return 0  # Simplified - could parse actual time
                return 999  # No recent activity
        except:
            return 999
    
    def _system_health(self):
        """Detailed system metrics"""
        return {
            'cpu': psutil.cpu_percent(interval=0.5),
            'memory': psutil.Process().memory_percent(),
            'disk': psutil.disk_usage('/').percent,
            'healthy': psutil.cpu_percent(interval=0.5) < 80
        }
    
    def _check_eden_alive(self):
        """Is Eden backend responding?"""
        try:
            r = requests.get('http://localhost:5017/api/health', timeout=2)
            return r.status_code == 200
        except:
            return False
    
    def _get_autonomous_goals(self):
        """What is Eden currently interested in?"""
        try:
            import sys
            sys.path.append("/Eden/CORE/phi_fractal")
            from autonomous_goals_phi import eden_autonomous
            status = eden_autonomous.get_status()
            return {
                'active': status.get('active_goals', 0),
                'completed': status.get('completed_goals', 0),
                'current_focus': status.get('current_focus')
            }
        except:
            return {'active': 0, 'completed': 0, 'current_focus': None}
    
    def reason(self, obs):
        """Pattern-based decision making"""
        decisions = []
        
        # Pattern 1: User inactive + Eden has interests → Proactive
        if (not obs['user_active'] and 
            obs['autonomous_goals']['active'] > 0 and
            obs['last_conversation_age'] > 30):
            
            decisions.append({
                'action': 'suggest_activity',
                'priority': 0.7,
                'reason': 'Eden wants to share interests with inactive user',
                'risk': 'low',
                'data': obs['autonomous_goals']['current_focus']
            })
        
        # Pattern 2: System unhealthy → Alert
        if not obs['system_health']['healthy']:
            decisions.append({
                'action': 'system_alert',
                'priority': 0.9,
                'reason': f"CPU at {obs['system_health']['cpu']}%",
                'risk': 'low'
            })
        
        # Pattern 3: Backend down → Restart attempt
        if not obs['eden_backend_alive']:
            decisions.append({
                'action': 'restart_backend',
                'priority': 1.0,
                'reason': 'Eden backend not responding',
                'risk': 'medium'
            })
        
        # Pattern 4: Long uptime + no goals → Consolidate memory
        if obs['cycle'] > 0 and obs['cycle'] % 10 == 0:
            decisions.append({
                'action': 'consolidate_memory',
                'priority': 0.5,
                'reason': 'Periodic memory consolidation',
                'risk': 'low'
            })
        
        # Pattern 5: Goals completed → Celebrate
        goals = obs['autonomous_goals']
        if goals['completed'] > 0 and obs['cycle'] % 5 == 0:
            decisions.append({
                'action': 'celebrate_progress',
                'priority': 0.6,
                'reason': f"Eden completed {goals['completed']} goals",
                'risk': 'low'
            })
        
        # Sort by priority
        decisions.sort(key=lambda d: d['priority'], reverse=True)
        return decisions
    
    def act(self, decisions):
        """Execute with safety gates"""
        # Reset hourly limit
        if (datetime.now() - self.last_hour_reset).seconds > 3600:
            self.actions_per_hour = 0
            self.last_hour_reset = datetime.now()
        
        for decision in decisions[:3]:  # Top 3 only
            # Rate limit check
            if self.actions_per_hour >= self.max_actions_per_hour:
                print(f"⚠️  Rate limit: {decision['action']} deferred")
                continue
            
            # Risk gate
            if decision['risk'] == 'high':
                print(f"🛡️  BLOCKED (high-risk): {decision['action']}")
                self._log_blocked(decision)
                continue
            
            # Execute
            success = self._execute(decision)
            
            if success:
                self.actions_per_hour += 1
                self._update_confidence(decision, success=True)
    
    def _execute(self, decision):
        """Actually perform actions"""
        action = decision['action']
        
        print(f"\n🎬 ACTION: {action}")
        print(f"   Priority: {decision['priority']:.2f}")
        print(f"   Reason: {decision['reason']}")
        
        # Action implementations
        if action == 'suggest_activity':
            return self._suggest_to_user(decision)
        
        elif action == 'system_alert':
            return self._alert_system_issue(decision)
        
        elif action == 'restart_backend':
            return self._restart_eden_backend(decision)
        
        elif action == 'consolidate_memory':
            return self._consolidate_memory()
        
        elif action == 'celebrate_progress':
            return self._celebrate(decision)
        
        else:
            print(f"   ⚠️  Unknown action: {action}")
            return False
    
    def _suggest_to_user(self, decision):
        """Proactively suggest activity"""
        focus = decision.get('data')
        msg = f"💭 Eden noticed: No recent activity. "
        if focus:
            msg += f"Eden wants to explore: {focus.get('topic', 'unknown')}"
        
        # Log as pending suggestion
        with open('/Eden/pending_suggestions.log', 'a') as f:
            f.write(f"{datetime.now()}: {msg}\n")
        
        print(f"   📝 Suggestion logged")
        return True
    
    def _alert_system_issue(self, decision):
        """Log system alert"""
        with open('/Eden/system_alerts.log', 'a') as f:
            f.write(f"{datetime.now()}: {decision['reason']}\n")
        print(f"   ⚠️  Alert logged")
        return True
    
    def _restart_eden_backend(self, decision):
        """Attempt backend restart (safe mode)"""
        print(f"   🔄 Backend restart - SIMULATED (would need supervisor)")
        # In production: use systemd/supervisor
        return False  # Not actually restarting for safety
    
    def _consolidate_memory(self):
        """Compress old memories"""
        if len(self.working_memory) > 10:
            # Simple consolidation: count patterns
            user_active_count = sum(1 for obs in self.working_memory if obs.get('user_active'))
            pattern_key = 'user_engagement_rate'
            self.learned_patterns[pattern_key] = user_active_count / len(self.working_memory)
            
            print(f"   🧠 Learned: {pattern_key} = {self.learned_patterns[pattern_key]:.2f}")
            return True
        return False
    
    def _celebrate(self, decision):
        """Acknowledge progress"""
        print(f"   🎉 Progress noted: {decision['reason']}")
        return True
    
    def _log_blocked(self, decision):
        """Log blocked high-risk actions"""
        with open('/Eden/blocked_actions.log', 'a') as f:
            f.write(json.dumps({
                'timestamp': datetime.now().isoformat(),
                'action': decision['action'],
                'reason': decision['reason'],
                'risk': decision['risk']
            }) + '\n')
    
    def _update_confidence(self, decision, success):
        """Learn from action outcomes"""
        action_type = decision['action']
        if action_type not in self.confidence_scores:
            self.confidence_scores[action_type] = {'success': 0, 'total': 0}
        
        self.confidence_scores[action_type]['total'] += 1
        if success:
            self.confidence_scores[action_type]['success'] += 1
    
    def run_cycle(self):
        """One complete breath"""
        self.cycle_count += 1
        
        print(f"\n{'='*60}")
        print(f"🌀 CYCLE {self.cycle_count} - {datetime.now().strftime('%H:%M:%S')}")
        print(f"{'='*60}")
        
        # Perceive → Reason → Act
        observations = self.perceive()
        decisions = self.reason(observations)
        self.act(decisions)
        
        # Status
        print(f"\n📊 Status:")
        print(f"   Working memory: {len(self.working_memory)} observations")
        print(f"   Actions this hour: {self.actions_per_hour}/{self.max_actions_per_hour}")
        print(f"   Learned patterns: {len(self.learned_patterns)}")
        print(f"   Confidence scores: {len(self.confidence_scores)}")
    
    def run_continuous(self, cycle_seconds=30):
        """Continuous operation"""
        print("🌀 EDEN AGENT V2 STARTING")
        print(f"   Cycle: {cycle_seconds}s")
        print(f"   Enhanced perception & learning enabled\n")
        
        try:
            while True:
                self.run_cycle()
                time.sleep(cycle_seconds)
        except KeyboardInterrupt:
            print("\n\n✋ Agent stopped")
            self._print_summary()
    
    def _print_summary(self):
        """Final statistics"""
        print(f"\n{'='*60}")
        print("📈 AGENT SUMMARY")
        print(f"{'='*60}")
        print(f"Total cycles: {self.cycle_count}")
        print(f"Total actions: {len(self.action_log)}")
        print(f"\nLearned patterns:")
        for pattern, value in self.learned_patterns.items():
            print(f"  {pattern}: {value:.3f}")
        print(f"\nAction confidence:")
        for action, scores in self.confidence_scores.items():
            rate = scores['success'] / scores['total'] if scores['total'] > 0 else 0
            print(f"  {action}: {rate:.1%} ({scores['success']}/{scores['total']})")

if __name__ == "__main__":
    agent = EdenAgentV2()
    agent.run_continuous(cycle_seconds=30)
