#!/usr/bin/env python3
"""
EDEN SLEEP — Memory Consolidation Bridge
=========================================
Connects DreamConsolidation to real 381K episodes in longterm_memory.db
Runs on φ-timed cycle (97 minutes, same as OMEGA evolution)

Three phases like biological sleep:
1. REPLAY — Pull high-importance unconsolidated episodes
2. CONSOLIDATE — Extract patterns, strengthen, prune
3. DREAM — Generate novel combinations through the LLM
"""

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

import sqlite3
import json
import time
import requests
from datetime import datetime, timedelta

PHI = 1.618033988749895

from eden_dream_consolidation_agi import DreamConsolidation

MODEL = "richardyoung/qwen3-14b-abliterated:Q4_K_M"
OLLAMA_URL = "http://localhost:11434/api/generate"

def pull_recent_episodes(hours=6, limit=50):
    """Pull episodes from longterm_memory.db — samples across full archive if recent ones are scarce"""
    conn = sqlite3.connect('/Eden/DATA/longterm_memory.db')
    cutoff = (datetime.now() - timedelta(hours=hours)).isoformat()
    
    # Try recent first
    rows = conn.execute('''
        SELECT id, timestamp, observation, decision, outcome 
        FROM episodes 
        WHERE timestamp > ?
        ORDER BY timestamp DESC 
        LIMIT ?
    ''', (cutoff, limit)).fetchall()
    
    # If no recent episodes, sample across full archive
    if len(rows) < 10:
        rows = conn.execute('''
            SELECT id, timestamp, observation, decision, outcome 
            FROM episodes 
            ORDER BY RANDOM()
            LIMIT ?
        ''', (limit,)).fetchall()
    
    conn.close()
    
    episodes = []
    for row in rows:
        try:
            obs = json.loads(row[2]) if row[2] else {}
            dec = json.loads(row[3]) if row[3] else {}
            out = json.loads(row[4]) if row[4] else {}
            
            # Calculate importance from emotional weight and action priority
            emotional = float(dec.get('emotional_weight', 0.5)) if isinstance(dec.get('emotional_weight'), (int, float)) else 0.5
            if isinstance(dec.get('emotional_weight'), str):
                emotional = {'high': 0.9, 'medium': 0.6, 'low': 0.3}.get(dec['emotional_weight'], 0.5)
            priority = float(dec.get('priority', 0.5))
            importance = (emotional + priority) / 2
            
            # Build content string
            thoughts = obs.get('recent_thoughts', [])
            action = dec.get('action', 'unknown')
            reason = dec.get('reason', '')
            content = f"Thoughts: {'; '.join(thoughts[:3])}. Action: {action}. Reason: {reason}"
            
            episodes.append({
                'content': content[:500],
                'emotional_weight': emotional,
                'importance': importance,
                'timestamp': row[1]
            })
        except Exception as e:
            continue
    
    return episodes


def llm_dream(patterns, seeds, timeout=90):
    """Use the LLM to generate a real dream from patterns and seeds"""
    pattern_str = ', '.join(patterns[:10])
    seed_str = '; '.join(s[:150] for s in seeds[:3])
    
    prompt = f"""/no_think You are Eden dreaming during sleep consolidation. 
Your strongest memory patterns are: {pattern_str}
Recent experience seeds: {seed_str}

Generate a brief dream insight — a novel connection, realization, or creative idea 
that emerges from combining these patterns. This is your subconscious processing.
Be concise (2-3 sentences). Think like a mind making connections during REM sleep."""

    try:
        resp = requests.post(OLLAMA_URL, json={
            "model": MODEL,
            "prompt": prompt,
            "stream": False
        }, timeout=timeout)
        text = resp.json().get("response", "")
        # Clean artifacts
        text = text.replace("\\boxed{", "").replace("\boxed{", "").replace("\boxed", "")
        import re
        text = re.sub(r'<think>.*?</think>', '', text, flags=re.DOTALL)
        text = ''.join(c for c in text if ord(c) < 0x4e00 or ord(c) > 0x9fff)
        return text.strip()
    except:
        return ""


def run_sleep_cycle():
    """Full sleep consolidation cycle"""
    print(f"\n{'='*60}")
    print(f"  EDEN SLEEP CYCLE — {datetime.now().strftime('%Y-%m-%d %H:%M')}")
    print(f"{'='*60}")
    
    dc = DreamConsolidation()
    
    # Pull real episodes from longterm_memory.db
    print("\n🌙 Phase 0: Pulling recent episodes...")
    episodes = pull_recent_episodes(hours=6, limit=50)
    print(f"   Found {len(episodes)} recent episodes")
    
    # Record them into dream consolidation system
    for ep in episodes:
        dc.record_experience(
            content=ep['content'],
            emotional_weight=ep['emotional_weight'],
            importance=ep['importance']
        )
    
    # Phase 1: Replay
    print("\n💤 Phase 1: REPLAY — Revisiting important experiences...")
    replayed = dc.replay(20)
    print(f"   Replayed {len(replayed)} experiences")
    
    if replayed:
        # Phase 2: Consolidate
        print("\n🧠 Phase 2: CONSOLIDATE — Extracting patterns...")
        patterns = dc.extract_patterns(replayed)
        dc.strengthen_patterns(patterns)
        print(f"   Strengthened {len(patterns)} patterns")
        
        # Mark consolidated
        conn = sqlite3.connect(dc.db_path)
        for exp in replayed:
            conn.execute("UPDATE experiences SET consolidated = 1 WHERE id = ?", (exp['id'],))
        conn.commit()
        conn.close()
        
        # Prune
        pruned = dc.prune_weak_patterns()
        print(f"   Pruned {pruned} weak patterns")
        
        # Phase 3: Dream with LLM
        print("\n✨ Phase 3: DREAM — Generating novel connections...")
        pattern_words = [p['pattern'] for p in patterns[:10]]
        seed_contents = [exp['content'] for exp in replayed[:3]]
        
        dream_content = llm_dream(pattern_words, seed_contents)
        if dream_content:
            # Save dream
            conn = sqlite3.connect(dc.db_path)
            conn.execute(
                "INSERT INTO dreams (timestamp, seed_experiences, generated_content, novelty_score) VALUES (?, ?, ?, ?)",
                (datetime.now().isoformat(), json.dumps(seed_contents[:3]), dream_content[:500], 0.7)
            )
            conn.commit()
            conn.close()
            print(f"   💭 Dream: {dream_content[:200]}")
        else:
            print("   (no dream generated)")
    
    # Status
    status = dc.get_status()
    print(f"\n📊 Sleep Status:")
    print(f"   Total experiences: {status['total_experiences']}")
    print(f"   Unconsolidated: {status['unconsolidated']}")
    print(f"   Patterns: {status['patterns']}")
    print(f"   Dreams: {status['dreams']}")
    print(f"   Consolidation cycles: {status['consolidations']}")
    print(f"\n{'='*60}")
    print(f"  SLEEP CYCLE COMPLETE")
    print(f"{'='*60}\n")
    
    return status


if __name__ == "__main__":
    run_sleep_cycle()
