"""
Auto-generate handoff reports from cascades data - TOKEN EFFICIENT

Generates semantic handoff summaries (~500 tokens) from session cascades,
avoiding token bloat from storing full cascade data.
"""

import json
import logging
from typing import Dict, List, Optional
from datetime import datetime

logger = logging.getLogger(__name__)


def auto_generate_handoff(session_id: str, db_path: str = "./.empirica/sessions/sessions.db") -> Dict:
    """
    Auto-generate handoff report from cascades data in database.
    
    Token efficiency: ~500 tokens vs 2000+ if storing full cascade data
    
    Args:
        session_id: Session UUID
        db_path: Path to session database
        
    Returns:
        dict: Handoff report data ready for storage
        
    Raises:
        ValueError: If session not found or no cascades exist
    """
    from empirica.data.session_database import SessionDatabase
    
    db = SessionDatabase(db_path=db_path)
    
    try:
        # 1. Get session metadata
        cursor = db.conn.cursor()
        cursor.execute("""
            SELECT ai_id, start_time, end_time, bootstrap_level, total_cascades
            FROM sessions
            WHERE session_id = ?
        """, (session_id,))
        
        session = cursor.fetchone()
        if not session:
            raise ValueError(f"Session {session_id} not found")
        
        ai_id, start_time, end_time, bootstrap_level, total_cascades = session
        
        # 2. Get all cascades for this session
        cursor.execute("""
            SELECT cascade_id, task, context_json, epistemic_delta,
                   started_at, completed_at, final_confidence
            FROM cascades
            WHERE session_id = ?
            ORDER BY started_at ASC
        """, (session_id,))
        
        cascades = cursor.fetchall()
        
        if not cascades:
            raise ValueError(f"No cascades found for session {session_id}")
        
        # 3. Extract task summary from first cascade
        first_cascade = cascades[0]
        task_summary = first_cascade[1]  # task column
        
        # 4. Calculate epistemic trajectory (COMPACT!)
        knowledge_trajectory = []
        uncertainty_trajectory = []
        key_learning_moments = []
        
        prev_know = 0.5
        for i, cascade in enumerate(cascades, 1):
            epistemic_delta = cascade[3]  # epistemic_delta column
            if epistemic_delta:
                try:
                    delta_data = json.loads(epistemic_delta)
                    know = delta_data.get('know', 0.5)
                    uncertainty = delta_data.get('uncertainty', 0.5)
                    
                    knowledge_trajectory.append(round(know, 2))
                    uncertainty_trajectory.append(round(uncertainty, 2))
                    
                    # Track significant learning moments (>0.10 increase)
                    if know - prev_know > 0.10:
                        task = cascade[1][:50]  # First 50 chars of task
                        key_learning_moments.append(
                            f"CASCADE {i}: {task}... (+{know - prev_know:.2f} knowledge)"
                        )
                    prev_know = know
                except:
                    pass
        
        # 5. Extract key findings from CHECK phases and investigation logs
        key_findings = []
        investigation_notes = []
        actions_taken = []
        
        for cascade in cascades:
            context_json = cascade[2]
            if context_json:
                try:
                    context = json.loads(context_json)
                    
                    # Extract CHECK findings
                    if 'check_findings' in context:
                        findings = context['check_findings']
                        if isinstance(findings, list):
                            key_findings.extend(findings)
                    
                    # Extract investigation log
                    if 'investigation_log' in context:
                        for log_entry in context['investigation_log']:
                            if 'findings' in log_entry:
                                investigation_notes.extend(log_entry['findings'])
                    
                    # Extract actions from act log
                    if 'act_log' in context:
                        for act_entry in context['act_log']:
                            if 'actions' in act_entry:
                                actions_taken.extend(act_entry['actions'])
                except:
                    pass
        
        # Combine and deduplicate findings
        all_findings = key_findings + investigation_notes
        key_findings = list(dict.fromkeys(all_findings))[:5]
        
        # 6. Get remaining unknowns from last CHECK
        remaining_unknowns = []
        if cascades:
            last_context_json = cascades[-1][2]
            if last_context_json:
                try:
                    last_context = json.loads(last_context_json)
                    unknowns = last_context.get('check_unknowns', [])
                    if isinstance(unknowns, list):
                        remaining_unknowns = unknowns[:3]  # Top 3 only
                except:
                    pass
        
        # 7. Get artifacts from git diff (simplified - just note that files were modified)
        artifacts = _get_artifacts_from_session(session_id, start_time)
        
        # 8. Auto-generate next session context
        if knowledge_trajectory:
            first_know = knowledge_trajectory[0]
            last_know = knowledge_trajectory[-1]
            confidence_delta = last_know - first_know
            
            if confidence_delta > 0.2:
                next_context = f"High confidence gained (+{confidence_delta:.2f}). Work validated and ready for next phase."
            elif confidence_delta > 0.1:
                next_context = f"Moderate progress (+{confidence_delta:.2f}). Review findings before proceeding."
            else:
                next_context = f"Minimal change ({confidence_delta:+.2f}). Some unknowns remain - investigate further."
        else:
            next_context = "No epistemic data available. Manual review recommended."
        
        # 9. Calculate duration
        duration_seconds = 0
        if start_time and end_time:
            try:
                start_dt = datetime.fromisoformat(start_time)
                end_dt = datetime.fromisoformat(end_time)
                duration_seconds = int((end_dt - start_dt).total_seconds())
            except:
                pass
        
        # 10. Build compact handoff report
        return {
            "session_id": session_id,
            "ai_id": ai_id,
            "task_summary": task_summary,
            "key_findings": key_findings if key_findings else ["No findings captured"],
            "remaining_unknowns": remaining_unknowns if remaining_unknowns else [],
            "next_session_context": next_context,
            "artifacts_created": artifacts,
            "actions_completed": actions_taken[:10] if actions_taken else [],  # Top 10 actions
            "epistemic_deltas": {
                "knowledge_trajectory": " → ".join(map(str, knowledge_trajectory)) if knowledge_trajectory else "N/A",
                "uncertainty_trajectory": " → ".join(map(str, uncertainty_trajectory)) if uncertainty_trajectory else "N/A",
                "overall_delta": f"+{knowledge_trajectory[-1] - knowledge_trajectory[0]:.2f}" if len(knowledge_trajectory) >= 2 else "N/A",
                "key_learning_moments": key_learning_moments[:3]  # Top 3 only
            },
            "productivity_metrics": {
                "cascades_run": len(cascades),
                "findings_discovered": len(all_findings),
                "actions_taken": len(actions_taken)
            },
            "duration_seconds": duration_seconds,
            "cascades_completed": len(cascades),
            "timestamp": datetime.utcnow().isoformat()
        }
        
    finally:
        db.close()


def _get_artifacts_from_session(session_id: str, start_time: str) -> List[str]:
    """
    Get list of files modified during session using git diff.
    
    Args:
        session_id: Session UUID
        start_time: Session start timestamp
        
    Returns:
        List of modified file paths
    """
    import subprocess
    
    try:
        # Try to get git diff since session start
        if start_time:
            # Get files changed since start_time
            result = subprocess.run(
                ['git', 'diff', '--name-only', f'@{{since={start_time}}}'],
                capture_output=True,
                text=True,
                timeout=5
            )
            
            if result.returncode == 0 and result.stdout.strip():
                files = [f.strip() for f in result.stdout.strip().split('\n') if f.strip()]
                return files[:10]  # Limit to 10 files
    except Exception as e:
        logger.debug(f"Could not get git diff: {e}")
    
    # Fallback: return empty list
    return []


def close_session(session_id: str, db_path: str = "./.empirica/sessions/sessions.db") -> None:
    """
    Close session by setting end_time in database.
    
    Args:
        session_id: Session UUID
        db_path: Path to session database
    """
    from empirica.data.session_database import SessionDatabase
    
    db = SessionDatabase(db_path=db_path)
    
    try:
        cursor = db.conn.cursor()
        cursor.execute("""
            UPDATE sessions
            SET end_time = ?
            WHERE session_id = ?
        """, (datetime.utcnow().isoformat(), session_id))
        
        db.conn.commit()
        logger.info(f"Session {session_id} closed successfully")
        
    finally:
        db.close()
