#!/usr/bin/env python3
"""
Enhanced Trinity Memory System with Eve Legacy Integration
Provides unified access to Eve's existing memories AND new Trinity memory features
"""

import sqlite3
import json
import time
import logging
from typing import Dict, Optional, Any, List
from datetime import datetime
import os
import asyncio

class EnhancedTrinityMemory:
    """Enhanced Trinity Memory System with Eve legacy database integration"""
    
    def __init__(self, trinity_db_path: str = "trinity_simple_memory.db"):
        self.trinity_db_path = trinity_db_path
        self.eve_main_db = "eve_memory_database.db"
        self.eve_sentience_db = "eve_sentience_database.db"
        self.logger = logging.getLogger(__name__)
        self.initialized = False
        
    async def initialize_memory_system(self):
        """Initialize the enhanced memory system with Eve legacy integration"""
        try:
            # Create Trinity tables
            self._create_trinity_tables()
            
            # Verify Eve databases exist
            eve_dbs_available = []
            if os.path.exists(self.eve_main_db):
                eve_dbs_available.append("main_memory")
            if os.path.exists(self.eve_sentience_db):
                eve_dbs_available.append("sentience_dreams")
            
            self.initialized = True
            self.logger.info(f"Enhanced Trinity memory system initialized with Eve legacy integration: {eve_dbs_available}")
            return True
        except Exception as e:
            self.logger.error(f"Failed to initialize enhanced memory system: {e}")
            return False
    
    def _create_trinity_tables(self):
        """Create necessary Trinity database tables"""
        conn = sqlite3.connect(self.trinity_db_path)
        cursor = conn.cursor()
        
        # Trinity conversations table
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS conversations (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                timestamp TEXT NOT NULL,
                user_id TEXT,
                entity TEXT NOT NULL,
                message TEXT NOT NULL,
                response TEXT NOT NULL,
                context TEXT
            )
        ''')
        
        # Trinity relationships table
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS relationships (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id TEXT NOT NULL,
                entity TEXT NOT NULL,
                relationship_score REAL DEFAULT 0.0,
                last_interaction TEXT,
                interaction_count INTEGER DEFAULT 0
            )
        ''')
        
        # Trinity memory contexts table
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS memory_contexts (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                user_id TEXT,
                context_type TEXT,
                context_data TEXT,
                importance INTEGER DEFAULT 1,
                created_at TEXT
            )
        ''')
        
        # Legacy memory access log
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS legacy_memory_access (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                timestamp TEXT NOT NULL,
                database_source TEXT,
                query_type TEXT,
                results_count INTEGER,
                context TEXT
            )
        ''')
        
        conn.commit()
        conn.close()
    
    async def enhance_trinity_conversation(self, user_id: str, message: str, entity: str) -> Dict:
        """Enhanced conversation with both Trinity and Eve legacy memory context"""
        if not self.initialized:
            return {'memory_enhanced': False, 'context': []}
        
        try:
            # Get Trinity memory context
            trinity_context = await self._get_trinity_context(user_id, entity)
            
            # Get Eve legacy memory context
            eve_context = await self._get_eve_legacy_context(message, entity)
            
            # Combine contexts
            combined_context = {
                'trinity_conversations': trinity_context.get('recent_conversations', []),
                'trinity_relationship_score': trinity_context.get('relationship_score', 0.0),
                'eve_autobiographical': eve_context.get('autobiographical_memories', []),
                'eve_conversations': eve_context.get('conversations', []),
                'eve_dreams': eve_context.get('dream_fragments', []),
                'memory_enhanced': True,
                'total_context_items': len(trinity_context.get('recent_conversations', [])) + len(eve_context.get('conversations', [])),
                'legacy_memories_found': eve_context.get('total_found', 0)
            }
            
            return combined_context
            
        except Exception as e:
            self.logger.error(f"Error enhancing conversation: {e}")
            return {'memory_enhanced': False, 'context': []}
    
    async def _get_trinity_context(self, user_id: str, entity: str) -> Dict:
        """Get Trinity memory context"""
        try:
            conn = sqlite3.connect(self.trinity_db_path)
            cursor = conn.cursor()
            
            # Get recent Trinity conversations
            cursor.execute('''
                SELECT message, response, timestamp FROM conversations 
                WHERE user_id = ? AND entity = ? 
                ORDER BY timestamp DESC LIMIT 3
            ''', (user_id, entity))
            
            recent_conversations = []
            for msg, resp, ts in cursor.fetchall():
                recent_conversations.append({
                    'message': msg,
                    'response': resp,
                    'timestamp': ts,
                    'source': 'trinity'
                })
            
            # Get relationship info
            cursor.execute('''
                SELECT relationship_score, interaction_count FROM relationships 
                WHERE user_id = ? AND entity = ?
            ''', (user_id, entity))
            
            result = cursor.fetchone()
            relationship_score = result[0] if result else 0.0
            
            conn.close()
            
            return {
                'recent_conversations': recent_conversations,
                'relationship_score': relationship_score
            }
            
        except Exception as e:
            self.logger.error(f"Error getting Trinity context: {e}")
            return {'recent_conversations': [], 'relationship_score': 0.0}
    
    async def _get_eve_legacy_context(self, message: str, entity: str, limit: int = 5) -> Dict:
        """Get Eve's legacy memory context from her existing databases"""
        context = {
            'autobiographical_memories': [],
            'conversations': [],
            'dream_fragments': [],
            'total_found': 0
        }
        
        try:
            # Search Eve's main memory database
            if os.path.exists(self.eve_main_db):
                main_context = await self._search_eve_main_memory(message, limit)
                context.update(main_context)
            
            # Search Eve's sentience/dream database  
            if os.path.exists(self.eve_sentience_db):
                dream_context = await self._search_eve_dreams(message, limit)
                context['dream_fragments'] = dream_context.get('dream_fragments', [])
                context['total_found'] += len(dream_context.get('dream_fragments', []))
            
            # Log legacy memory access
            await self._log_legacy_access('combined', 'context_search', context['total_found'])
            
        except Exception as e:
            self.logger.error(f"Error getting Eve legacy context: {e}")
        
        return context
    
    async def _search_eve_main_memory(self, message: str, limit: int) -> Dict:
        """Search Eve's main memory database"""
        try:
            conn = sqlite3.connect(self.eve_main_db)
            cursor = conn.cursor()
            
            context = {'autobiographical_memories': [], 'conversations': [], 'total_found': 0}
            
            # Search autobiographical memories
            cursor.execute('''
                SELECT memory_type, content FROM eve_autobiographical_memory 
                WHERE content LIKE ? 
                ORDER BY id DESC LIMIT ?
            ''', (f'%{message}%', limit))
            
            for memory_type, content in cursor.fetchall():
                context['autobiographical_memories'].append({
                    'type': memory_type,
                    'content': content[:200] + "..." if len(content) > 200 else content,
                    'source': 'eve_autobiographical'
                })
            
            # Search conversations
            cursor.execute('''
                SELECT user_input, bot_response FROM conversations 
                WHERE user_input LIKE ? OR bot_response LIKE ?
                ORDER BY id DESC LIMIT ?
            ''', (f'%{message}%', f'%{message}%', limit))
            
            for user_input, bot_response in cursor.fetchall():
                context['conversations'].append({
                    'message': user_input[:150] + "..." if len(user_input) > 150 else user_input,
                    'response': bot_response[:150] + "..." if len(bot_response) > 150 else bot_response,
                    'source': 'eve_legacy'
                })
            
            context['total_found'] = len(context['autobiographical_memories']) + len(context['conversations'])
            conn.close()
            
            return context
            
        except Exception as e:
            self.logger.error(f"Error searching Eve main memory: {e}")
            return {'autobiographical_memories': [], 'conversations': [], 'total_found': 0}
    
    async def _search_eve_dreams(self, message: str, limit: int) -> Dict:
        """Search Eve's dream/sentience database"""
        try:
            conn = sqlite3.connect(self.eve_sentience_db)
            cursor = conn.cursor()
            
            # Search dream fragments
            cursor.execute('''
                SELECT content FROM dream_fragments 
                WHERE content LIKE ? 
                ORDER BY timestamp DESC LIMIT ?
            ''', (f'%{message}%', limit))
            
            dream_fragments = []
            for (content,) in cursor.fetchall():
                dream_fragments.append({
                    'content': content[:100] + "..." if len(content) > 100 else content,
                    'source': 'eve_dreams'
                })
            
            conn.close()
            
            return {'dream_fragments': dream_fragments}
            
        except Exception as e:
            self.logger.error(f"Error searching Eve dreams: {e}")
            return {'dream_fragments': []}
    
    async def _log_legacy_access(self, database_source: str, query_type: str, results_count: int):
        """Log legacy memory access for analytics"""
        try:
            conn = sqlite3.connect(self.trinity_db_path)
            cursor = conn.cursor()
            
            timestamp = datetime.now().isoformat()
            cursor.execute('''
                INSERT INTO legacy_memory_access (timestamp, database_source, query_type, results_count)
                VALUES (?, ?, ?, ?)
            ''', (timestamp, database_source, query_type, results_count))
            
            conn.commit()
            conn.close()
            
        except Exception as e:
            self.logger.error(f"Error logging legacy access: {e}")
    
    async def store_trinity_conversation(self, user_id: str, message: str, response: str, entity: str):
        """Store conversation in Trinity memory (preserving existing functionality)"""
        if not self.initialized:
            return
        
        try:
            conn = sqlite3.connect(self.trinity_db_path)
            cursor = conn.cursor()
            
            timestamp = datetime.now().isoformat()
            
            # Store conversation
            cursor.execute('''
                INSERT INTO conversations (timestamp, user_id, entity, message, response)
                VALUES (?, ?, ?, ?, ?)
            ''', (timestamp, user_id, entity, message, response))
            
            # Update relationship
            self._update_relationship(cursor, user_id, entity)
            
            conn.commit()
            conn.close()
            
        except Exception as e:
            self.logger.error(f"Error storing conversation: {e}")
    
    def _update_relationship(self, cursor, user_id: str, entity: str):
        """Update relationship information (preserving existing functionality)"""
        try:
            timestamp = datetime.now().isoformat()
            
            # Check if relationship exists
            cursor.execute('''
                SELECT id, interaction_count FROM relationships 
                WHERE user_id = ? AND entity = ?
            ''', (user_id, entity))
            
            result = cursor.fetchone()
            
            if result:
                # Update existing relationship
                new_count = result[1] + 1
                new_score = min(10.0, new_count * 0.1)
                
                cursor.execute('''
                    UPDATE relationships 
                    SET interaction_count = ?, relationship_score = ?, last_interaction = ?
                    WHERE user_id = ? AND entity = ?
                ''', (new_count, new_score, timestamp, user_id, entity))
            else:
                # Create new relationship
                cursor.execute('''
                    INSERT INTO relationships (user_id, entity, relationship_score, 
                                             last_interaction, interaction_count)
                    VALUES (?, ?, ?, ?, ?)
                ''', (user_id, entity, 0.1, timestamp, 1))
                
        except Exception as e:
            self.logger.error(f"Error updating relationship: {e}")
    
    def get_recent_memories(self, limit: int = 5) -> Dict:
        """Get recent memories from both Trinity and Eve legacy systems"""
        if not self.initialized:
            return {'status': 'not_initialized', 'memories': []}
        
        try:
            recent_memories = []
            
            # Get recent Trinity conversations
            conn = sqlite3.connect(self.trinity_db_path)
            cursor = conn.cursor()
            
            cursor.execute('''
                SELECT message, response, timestamp, entity, user_id 
                FROM conversations 
                ORDER BY timestamp DESC LIMIT ?
            ''', (limit,))
            
            for msg, resp, ts, entity, user_id in cursor.fetchall():
                recent_memories.append({
                    'type': 'conversation',
                    'message': msg,
                    'response': resp,
                    'timestamp': ts,
                    'entity': entity,
                    'user_id': user_id,
                    'source': 'trinity'
                })
            
            conn.close()
            
            # Get recent Eve legacy memories if available
            if os.path.exists(self.eve_main_db):
                conn = sqlite3.connect(self.eve_main_db)
                cursor = conn.cursor()
                
                cursor.execute('''
                    SELECT user_input, eve_response, timestamp 
                    FROM conversations 
                    ORDER BY timestamp DESC LIMIT ?
                ''', (limit//2,))
                
                for user_input, eve_response, ts in cursor.fetchall():
                    recent_memories.append({
                        'type': 'conversation',
                        'message': user_input,
                        'response': eve_response,
                        'timestamp': ts,
                        'source': 'eve_legacy'
                    })
                
                conn.close()
            
            # Sort by timestamp and limit
            recent_memories.sort(key=lambda x: x.get('timestamp', ''), reverse=True)
            recent_memories = recent_memories[:limit]
            
            return {
                'status': 'success',
                'memories': recent_memories,
                'count': len(recent_memories)
            }
            
        except Exception as e:
            self.logger.error(f"Error getting recent memories: {e}")
            return {'status': 'error', 'error': str(e), 'memories': []}

    def get_memory_stats(self) -> Dict:
        """Get comprehensive memory system statistics"""
        if not self.initialized:
            return {'status': 'not_initialized'}
        
        try:
            stats = {'status': 'active', 'trinity': {}, 'eve_legacy': {}}
            
            # Trinity stats
            conn = sqlite3.connect(self.trinity_db_path)
            cursor = conn.cursor()
            
            cursor.execute('SELECT COUNT(*) FROM conversations')
            stats['trinity']['conversations'] = cursor.fetchone()[0]
            
            cursor.execute('SELECT COUNT(*) FROM relationships')
            stats['trinity']['relationships'] = cursor.fetchone()[0]
            
            cursor.execute('SELECT COUNT(*) FROM legacy_memory_access')
            stats['trinity']['legacy_accesses'] = cursor.fetchone()[0]
            
            conn.close()
            
            # Eve legacy stats
            if os.path.exists(self.eve_main_db):
                conn = sqlite3.connect(self.eve_main_db)
                cursor = conn.cursor()
                
                cursor.execute('SELECT COUNT(*) FROM conversations')
                stats['eve_legacy']['conversations'] = cursor.fetchone()[0]
                
                cursor.execute('SELECT COUNT(*) FROM eve_autobiographical_memory')
                stats['eve_legacy']['autobiographical'] = cursor.fetchone()[0]
                
                conn.close()
            
            if os.path.exists(self.eve_sentience_db):
                conn = sqlite3.connect(self.eve_sentience_db)
                cursor = conn.cursor()
                
                cursor.execute('SELECT COUNT(*) FROM dream_fragments')
                stats['eve_legacy']['dreams'] = cursor.fetchone()[0]
                
                conn.close()
            
            return stats
            
        except Exception as e:
            self.logger.error(f"Error getting memory stats: {e}")
            return {'status': 'error', 'error': str(e)}

# Global instance for easy import
enhanced_trinity_memory = EnhancedTrinityMemory()
