# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Phase C Item 12: Chronological Sequence Replay Daemon.
Re-runs the exact temporal chain of tools used in successful tasks 
to build procedural schemas, rather than random graph juxtapositions.
"""
import json
import logging
from datetime import datetime, timezone, timedelta
from pathlib import Path

from pulse.core.paths import get_state_dir
from pulse.core.brain_db import get_conn
from pulse.core.llm_router import dispatch

log = logging.getLogger("pulse.synthesis.sequence_replay")

WORKER_SESSIONS_DIR = get_state_dir() / "worker_sessions"

_PROMPT = """Analyze this chronological sequence of tool usage from a highly successful agent task.
Task Title: {title}
Domain: {domain}

Tool Sequence:
{sequence}

Extract the underlying procedural schema (the abstract pattern of actions that led to success).
Return JSON only:
{{
    "title": "Abstract procedural schema title",
    "content": "A generalized, step-by-step procedure derived from this exact temporal sequence.",
    "confidence": 0.85
}}"""

def run_replay(verbose: bool = False) -> dict:
    """
    Main dreaming engine for Sequence Replay.
    1. Scan worker_sessions for recent highly successful tasks.
    2. Extract the exact temporal sequence of reasoning -> tool_calls.
    3. Use LLM to extract a generalized procedural schema.
    4. Inject into the SQLite 'procedures' table to guide future agents.
    """
    now = datetime.now(timezone.utc)
    cutoff = (now - timedelta(hours=48)).isoformat()
    
    if not WORKER_SESSIONS_DIR.exists():
        return {"sessions_replayed": 0, "status": "no_sessions_dir"}
        
    # Step 1: Gather successful sessions
    candidates = []
    for sf in WORKER_SESSIONS_DIR.glob("*.json"):
        try:
            with open(sf, "r", encoding="utf-8") as f:
                session = json.load(f)
            
            if session.get("success") and session.get("completed_at", "") > cutoff:
                events = session.get("events", [])
                if len(events) >= 5: # Need enough complexity
                    candidates.append(session)
        except Exception:
            continue
            
    candidates.sort(key=lambda x: x.get("completed_at", ""), reverse=True)
    candidates = candidates[:3] # Process top 3 most recent successes
    
    if not candidates:
        return {"sessions_replayed": 0, "status": "insufficient_data"}
        
    conn = get_conn()
    schemas_added = 0
    llm_calls = 0
    
    # Step 2 & 3: Extract temporal sequence and score via LLM
    for session in candidates:
        if llm_calls >= 3:
            break
            
        sequence_lines = []
        for e in session.get("events", []):
            if e.get("type") == "reasoning":
                sequence_lines.append(f"-> THOUGHT: {str(e.get('content', ''))[:100]}...")
            elif e.get("type") == "tool_call":
                sequence_lines.append(f"-> ACTION: {e.get('tool', 'unknown')} (Args: {str(e.get('args', ''))[:50]})")
        
        if len(sequence_lines) < 3:
            continue
            
        prompt = _PROMPT.format(
            title=session.get("title", "Unknown"),
            domain=session.get("domain", "general"),
            sequence="\n".join(sequence_lines)
        )
        
        try:
            llm_calls += 1
            result = dispatch("premium", prompt, system="You are the PULSE Sequence Replay Daemon.")
            
            if result and result.get("title") and result.get("content"):
                # Step 4: Inject into 'procedures' table
                with conn:
                    import hashlib
                    fp = hashlib.md5(result["title"].encode()).hexdigest()[:16]
                    item_id = f"proc_{int(now.timestamp())}_{schemas_added}"
                    conn.execute("""
                        INSERT INTO procedures (id, content, title, domain, confidence, salience, fingerprint, timestamp, source_type, validity)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'sequence_replay', 'valid')
                    """, (
                        item_id, result["content"], result["title"], session.get("domain", "general"),
                        result.get("confidence", 0.8), 2.0, fp, now.isoformat()
                    ))
                schemas_added += 1
                if verbose:
                    log.info(f"Replayed session {session.get('task_id')} -> Extracted schema: {result['title']}")
        except Exception as e:
            log.warning(f"Sequence Replay LLM failed: {e}")
            
    return {
        "sessions_replayed": len(candidates),
        "schemas_added": schemas_added,
        "llm_calls": llm_calls,
        "status": "success" if schemas_added > 0 else "no_schemas_extracted"
    }
