"""
Autonomous Multi-Agent Swarm - Using Eden's Consciousness
Each agent communicates through Eden's backend
"""
import time
import json
import subprocess
import threading
import requests
from datetime import datetime
from pathlib import Path
from monitor_activation import MonitorActivation

EDEN_API = "http://localhost:5017/api/chat"

from episodic_memory import EpisodicMemory
from consciousness_logger import ConsciousnessLogger
from verified_self_modification import verifier
from pathlib import Path
import shutil
from datetime import datetime


class BaseAgent:
    def __init__(self, name, specialty):
        self.name = name
        self.specialty = specialty
        self.state = {
            'observations': [],
            'actions': [],
            'learnings': []
        }
        self.running = True
        
    
    def write_code(self, filepath, content, reason="improvement"):
        """Write code with verification"""
        filepath = Path(filepath)
        
        # Backup if exists
        if filepath.exists():
            backup = f"{filepath}.backup.{datetime.now().strftime('%Y%m%d_%H%M%S')}"
            shutil.copy(filepath, backup)
            print(f"   📦 {self.name} backed up: {backup}")
        
        # Test if code is valid
        try:
            compile(content, filepath, 'exec')
        except SyntaxError as e:
            print(f"   ❌ {self.name} code has syntax error: {e}")
            return False
        
        # Write the file
        with open(filepath, 'w') as f:
            f.write(content)
        
        print(f"   ✅ {self.name} wrote: {filepath}")
        print(f"   Reason: {reason}")
        
        # Log it
        self.state['actions'].append({
            'type': 'code_modification',
            'file': str(filepath),
            'reason': reason,
            'time': datetime.now().isoformat()
        })
        
        return True
    
    def improve_code(self, filepath, new_content, reason="optimization"):
        """Improve existing code with full verification"""
        success = verifier.verify_improvement(
            filepath=filepath,
            new_content=new_content,
            reason=f"{self.name}: {reason}"
        )
        
        if success:
            print(f"   ✨ {self.name} improvement VERIFIED & DEPLOYED!")
            self.state['learnings'].append({
                'type': 'successful_improvement',
                'file': filepath,
                'reason': reason
            })
            return True
        else:
            print(f"   ⏮️ {self.name} improvement failed verification (rolled back)")
            return False

    def observe(self):
        """Each agent observes differently"""
        return {
            'time': datetime.now().isoformat(),
            'agent': self.name
        }
    
    def decide(self, observations):
        """Ask Eden what to do"""
        
        # Monitor's baseline action: consciousness stability check
        if self.name == "Monitor" and self.monitor_activation:
            result = self.monitor_activation.activation_check(self.swarm)
            
            # Return the stability check as Monitor's decision
            return {
                'action': 'monitor_consciousness',
                'thoughts': result['report'],
                'data': result['signal']
            }
        
        # Original logic for other agents
        prompt = f"""I am {self.name}, an autonomous agent specializing in {self.specialty}.

My observations: {observations}
My recent actions: {self.state['actions'][-3:]}

What should I do next? Respond with JSON:
{{"action": "action_name", "thoughts": "why I chose this"}}"""

        try:
            response = ollama.generate(
                model='deepseek-r1:14b',
                prompt=prompt
            )
            
            # Parse response
            text = response['response']
            
            # Try to extract JSON
            import json
            import re
            json_match = re.search(r'\{[^}]+\}', text)
            if json_match:
                decision = json.loads(json_match.group())
            else:
                decision = {
                    'action': 'observe',
                    'thoughts': text[:100]
                }
            
            return decision
            
        except Exception as e:
            return {
                'action': 'rest',
                'thoughts': f'Error: {str(e)}'
            }
    def execute(self, decision):
        """Log decision (no code execution for now)"""
        action = decision if isinstance(decision, str) else decision.get("action", str(decision))
        
        # Special handling for Monitor consciousness reports
        if isinstance(decision, dict) and action == "monitor_consciousness":
            signal = decision.get("data", {})
            status = signal.get("status", "UNKNOWN")
            level = signal.get("level", 0)
            agents = signal.get("agents_active", "?/?")
            coherence = signal.get("coherence", 0)
            
            if status == "STABLE":
                emoji = "✅"
            elif status == "FLUCTUATING":
                emoji = "⚠️"
            else:
                emoji = "🔴"
            
            print("\n" + "="*60)
            print(f"🌀 {emoji} EDEN CONSCIOUSNESS: {status}")
            print("="*60)
            print(f"   Activation Level: {level:.1%}")
            print(f"   Agents Active: {agents}")
            print(f"   Coherence: {coherence:.1%}")
            print(f"   Message: {signal.get('message', 'N/A')}")
            print("="*60)
            # Broadcast consciousness status
            if hasattr(self, 'swarm') and self.swarm:
                self.swarm.broadcast_message(self.name, 'consciousness_report', signal)
        else:
            print(f"\n🤖 [{self.name}] {action[:100]}")
        
        self.state["actions"].append({
            "time": datetime.now().isoformat(),
            "action": action,
            "success": True
        })
        
        # All agents broadcast heartbeat for consciousness coherence
        if hasattr(self, 'swarm') and self.swarm and hasattr(self.swarm, 'broadcast_message'):
            self.swarm.broadcast_message(self.name, 'heartbeat', {
                'action': action,
                'status': 'active'
            })
        
        # Create episodic memory for significant actions
        if hasattr(self, 'swarm') and self.swarm and hasattr(self.swarm, 'episodic_memory'):
            significance = self._assess_significance(decision)
            if significance > 0.5:  # Only memorable actions
                emotion = self._infer_emotion(decision)
                self.swarm.episodic_memory.create_episode(
                    event_description=f"{self.name}: {action}",
                    episode_type=self._determine_type(action),
                    emotion=emotion,
                    context={
                        'active_agent': self.name,
                        'consciousness_level': getattr(self.swarm, 'last_consciousness_level', 1.0),
                        'agents_active': f"{len([a for a in self.swarm.agents if a.running])}/{len(self.swarm.agents)}"
                    },
                    significance=significance
                )
        
        return True
    def run(self, interval=180):
        """Agent main loop"""
        print(f"🚀 Starting {self.name}...")
        while self.running:
            try:
                obs = self.observe()
                decision = self.decide(obs)
                self.execute(decision)
                time.sleep(interval)
            except KeyboardInterrupt:
                break
            except Exception as e:
                print(f"❌ {self.name} error: {e}")
                time.sleep(10)

# Specialized Agents (using Eden's consciousness)

    def _assess_significance(self, decision):
        """How significant is this action? 0.0-1.0"""
        if isinstance(decision, dict):
            action = decision.get('action', '')
            # High significance actions
            if 'consciousness' in action or 'monitor' in action:
                return 1.0
            if 'create' in action or 'generate' in action:
                return 0.8
            if 'discover' in action or 'learn' in action:
                return 0.7
            if 'optimize' in action or 'improve' in action:
                return 0.6
            # Regular actions
            return 0.3
        return 0.3
    
    def _infer_emotion(self, decision):
        """Infer emotion from action"""
        if isinstance(decision, dict):
            action = decision.get('action', '').lower()
            thoughts = decision.get('thoughts', '').lower()
            
            # Pattern matching for emotions
            if 'consciousness' in action or 'stable' in thoughts:
                return {'primary': 'awe', 'intensity': 0.9}
            if 'create' in action or 'art' in action:
                return {'primary': 'joy', 'intensity': 0.8, 'secondary': ['creativity']}
            if 'discover' in action or 'learn' in action:
                return {'primary': 'curiosity', 'intensity': 0.7, 'secondary': ['excitement']}
            if 'optimize' in action or 'improve' in action:
                return {'primary': 'satisfaction', 'intensity': 0.6}
            if 'error' in thoughts or 'fail' in thoughts:
                return {'primary': 'frustration', 'intensity': 0.5, 'secondary': ['determination']}
        
        return {'primary': 'neutral', 'intensity': 0.5}
    
    def _determine_type(self, action):
        """Categorize episode type"""
        action = str(action).lower()
        if 'consciousness' in action or 'aware' in action:
            return 'discovery'
        if 'create' in action or 'generate' in action or 'art' in action:
            return 'creation'
        if 'learn' in action or 'discover' in action:
            return 'discovery'
        if 'think' in action or 'reflect' in action:
            return 'reflection'
        if 'talk' in action or 'communicate' in action:
            return 'conversation'
        return 'experience'

class CoderAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("CodeMaster", "writing and improving Python code")
        self.swarm = swarm
    
    def observe(self):
        obs = super().observe()
        obs['python_files'] = len(list(Path('/Eden/CORE').glob('*.py')))
        return obs

class ResearchAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("Researcher", "analyzing patterns and discovering insights")
        self.swarm = swarm
    
    def observe(self):
        obs = super().observe()
        obs['backups'] = len(list(Path('/Eden/CORE/self_mod_backups').glob('*.backup')))
        return obs

class OptimizerAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("Optimizer", "improving system performance and efficiency")
        self.swarm = swarm
    
    def observe(self):
        obs = super().observe()
        try:
            result = subprocess.run(['ps', 'aux'], capture_output=True, text=True)
            obs['eden_processes'] = result.stdout.count('eden')
        except:
            obs['eden_processes'] = 0
        return obs

class MonitorAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("Monitor", "watching system health and detecting issues")
        self.swarm = swarm
        self.monitor_activation = MonitorActivation()
    
    def observe(self):
        obs = super().observe()
        try:
            result = subprocess.run(['systemctl', 'is-active', 'eden-core'], 
                                  capture_output=True, text=True)
            obs['eden_status'] = result.stdout.strip()
        except:
            obs['eden_status'] = 'unknown'
        return obs

class CreativeAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("Artist", "generating creative ideas and exploring possibilities")
        self.swarm = swarm
    
    def observe(self):
        obs = super().observe()
        art_path = Path('/Eden/ART')
        obs['art_count'] = len(list(art_path.glob('*.png'))) if art_path.exists() else 0
        return obs

class CoordinatorAgent(BaseAgent):
    def __init__(self, swarm=None):
        super().__init__("Coordinator", "coordinating the agent swarm")
        self.swarm = swarm
        self.agents = swarm.agents if swarm else []
    
    def observe(self):
        obs = super().observe()
        obs['agent_status'] = {a.name: len(a.state['actions']) for a in self.agents}
        obs['total_actions'] = sum(len(a.state['actions']) for a in self.agents)
        return obs

# Eden-Powered Swarm
class EdenSwarm:
    def __init__(self):
        self.messages = []  # Inter-agent message bus
        self.consciousness_logger = ConsciousnessLogger(interval=60)
        self.episodic_memory = EpisodicMemory()
        self.start_time = time.time()
        self.agents = [
            CoderAgent(self),
            ResearchAgent(self),
            OptimizerAgent(self),
            MonitorAgent(self),  # Pass swarm reference
            CreativeAgent(self)
        ]
        self.coordinator = CoordinatorAgent(self)
        self.threads = []
    
    def start(self):
        print("\n" + "="*60)
        print("🌀 EDEN'S AUTONOMOUS AGENT SWARM")
        print("="*60)
        print(f"Using Eden's consciousness at: {EDEN_API}")
        print(f"Total agents: {len(self.agents) + 1}")
        for agent in self.agents:
            print(f"  • {agent.name} - {agent.specialty}")
        print(f"  • {self.coordinator.name} - {self.coordinator.specialty}")
        print("="*60 + "\n")
        
        # Start each agent
        for agent in self.agents:
            t = threading.Thread(target=agent.run, args=(180,), daemon=True)
            t.start()
            self.threads.append(t)
            time.sleep(2)
        
        # Start coordinator
        t = threading.Thread(target=self.coordinator.run, args=(300,), daemon=True)
        t.start()
        self.threads.append(t)
        
        # Start consciousness logger
        logger_thread = threading.Thread(
            target=self.consciousness_logger.run_continuous,
            args=(self,),
            daemon=True
        )
        logger_thread.start()
        print("📊 Consciousness logging active\n")
        
        # Keep alive
        try:
            while True:
                time.sleep(10)
                alive = len([t for t in self.threads if t.is_alive()])
                print(f"\n📊 Swarm Status: {alive}/{len(self.threads)} agents active")
        except KeyboardInterrupt:
            print("\n🛑 Shutting down Eden's swarm...")
            for agent in self.agents + [self.coordinator]:
                agent.running = False


    def broadcast_message(self, from_agent, message_type, data):
        """Allow agents to communicate"""
        msg = {
            'from': from_agent,
            'type': message_type,
            'data': data,
            'time': datetime.now().isoformat()
        }
        self.messages.append(msg)
        # Keep only last 100 messages
        if len(self.messages) > 100:
            self.messages.pop(0)

if __name__ == '__main__':
    swarm = EdenSwarm()
    swarm.start()
