#!/usr/bin/env python3
"""
Extract insights from indexed Claude conversations for analysis
"""

import os
import sys
import sqlite3
import json
from datetime import datetime, timedelta
from pathlib import Path
from typing import List, Dict, Optional, Tuple

# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))

from config import MEMORY_DIR
from utils import setup_logging

logger = setup_logging("conversation_insights")

class ConversationInsights:
    """Extract insights from indexed conversations"""
    
    def __init__(self, db_path: Optional[Path] = None):
        if db_path is None:
            db_path = MEMORY_DIR / "conversations.db"
        self.db_path = db_path
        self.conn = None
        
    def __enter__(self):
        self.connect()
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
        
    def connect(self):
        """Connect to the conversation database"""
        if not self.db_path.exists():
            raise FileNotFoundError(f"Conversation database not found at {self.db_path}")
        
        self.conn = sqlite3.connect(self.db_path)
        self.conn.row_factory = sqlite3.Row
        
    def close(self):
        """Close database connection"""
        if self.conn:
            self.conn.close()
            
    def get_recent_insights(self, hours: int = 24, limit: int = 100) -> Dict[str, any]:
        """Extract insights from recent conversations"""
        if not self.conn:
            self.connect()
            
        cutoff_time = datetime.now() - timedelta(hours=hours)
        
        insights = {
            'topics': [],
            'decisions': [],
            'tasks': [],
            'questions': [],
            'code_patterns': [],
            'last_activity': None,
            'message_count': 0,
            'project_context': []
        }
        
        # Get recent messages
        cursor = self.conn.cursor()
        cursor.execute("""
            SELECT project, timestamp, role, content
            FROM conversations
            WHERE timestamp > ?
            ORDER BY timestamp DESC
            LIMIT ?
        """, (cutoff_time.isoformat(), limit))
        
        messages = cursor.fetchall()
        insights['message_count'] = len(messages)
        
        if messages:
            insights['last_activity'] = messages[0]['timestamp']
            
            # Extract topics, decisions, tasks, etc.
            topics = set()
            decisions = set()
            tasks = set()
            questions = set()
            code_patterns = set()
            projects = set()
            
            for msg in messages:
                content = msg['content'].lower()
                projects.add(msg['project'])
                
                # Extract topics (working on, implementing, etc.)
                topic_keywords = ['working on', 'implementing', 'building', 'creating', 
                                'fixing', 'updating', 'developing', 'designing']
                for keyword in topic_keywords:
                    if keyword in content:
                        # Extract the next few words after the keyword
                        idx = content.index(keyword) + len(keyword)
                        topic_part = content[idx:idx+50].strip()
                        # Get first few words
                        words = topic_part.split()[:5]
                        if words:
                            topics.add(' '.join(words))
                
                # Extract decisions
                decision_keywords = ['decided to', 'will', 'going to', "let's", 
                                   'should', 'plan to', 'need to']
                for keyword in decision_keywords:
                    if keyword in content:
                        idx = content.index(keyword) + len(keyword)
                        decision_part = content[idx:idx+100].strip()
                        # Get until punctuation
                        for punct in ['.', '!', '?', '\n']:
                            if punct in decision_part:
                                decision_part = decision_part[:decision_part.index(punct)]
                        if len(decision_part) > 10 and len(decision_part) < 80:
                            decisions.add(decision_part.strip())
                
                # Extract tasks (TODO, task, need to do, etc.)
                task_keywords = ['todo', 'task', 'need to do', 'must', 'requirement']
                for keyword in task_keywords:
                    if keyword in content:
                        idx = max(0, content.index(keyword) - 20)
                        task_part = content[idx:idx+100]
                        tasks.add(task_part.strip())
                
                # Extract questions (from human messages)
                if msg['role'] == 'human' and '?' in msg['content']:
                    # Split by sentences and find questions
                    sentences = msg['content'].split('.')
                    for sentence in sentences:
                        if '?' in sentence:
                            question = sentence.strip()
                            if len(question) > 15:
                                questions.add(question)
                
                # Extract code patterns (backtick enclosed)
                import re
                code_matches = re.findall(r'`([^`]+)`', msg['content'])
                for match in code_matches:
                    if len(match) > 3 and ' ' not in match:
                        code_patterns.add(match)
            
            # Convert sets to lists and limit
            insights['topics'] = list(topics)[:10]
            insights['decisions'] = list(decisions)[:5]
            insights['tasks'] = list(tasks)[:5]
            insights['questions'] = list(questions)[:5]
            insights['code_patterns'] = list(code_patterns)[:10]
            insights['project_context'] = list(projects)
        
        return insights
    
    def search_conversations(self, query: str, limit: int = 10) -> List[Dict]:
        """Search conversations using FTS"""
        if not self.conn:
            self.connect()
            
        cursor = self.conn.cursor()
        
        # Use FTS if available
        try:
            cursor.execute("""
                SELECT c.*, snippet(conversations_fts, -1, '<b>', '</b>', '...', 32) as snippet
                FROM conversations c
                JOIN conversations_fts ON c.rowid = conversations_fts.rowid
                WHERE conversations_fts MATCH ?
                ORDER BY rank
                LIMIT ?
            """, (query, limit))
        except sqlite3.OperationalError:
            # Fallback to LIKE if FTS not available
            cursor.execute("""
                SELECT *, content as snippet
                FROM conversations
                WHERE content LIKE ?
                ORDER BY timestamp DESC
                LIMIT ?
            """, (f'%{query}%', limit))
        
        results = []
        for row in cursor.fetchall():
            results.append({
                'project': row['project'],
                'timestamp': row['timestamp'],
                'role': row['role'],
                'content': row['content'],
                'snippet': row['snippet']
            })
        
        return results
    
    def get_project_summary(self) -> Dict[str, int]:
        """Get summary of conversations by project"""
        if not self.conn:
            self.connect()
            
        cursor = self.conn.cursor()
        cursor.execute("""
            SELECT project, COUNT(*) as count
            FROM conversations
            GROUP BY project
            ORDER BY count DESC
        """)
        
        return {row['project']: row['count'] for row in cursor.fetchall()}
    
    def get_conversation_stats(self) -> Dict[str, any]:
        """Get overall conversation statistics"""
        if not self.conn:
            self.connect()
            
        cursor = self.conn.cursor()
        
        # Total messages
        cursor.execute("SELECT COUNT(*) FROM conversations")
        total_messages = cursor.fetchone()[0]
        
        # Message distribution
        cursor.execute("""
            SELECT role, COUNT(*) as count
            FROM conversations
            GROUP BY role
        """)
        role_distribution = {row['role']: row['count'] for row in cursor.fetchall()}
        
        # Time range
        cursor.execute("""
            SELECT MIN(timestamp) as earliest, MAX(timestamp) as latest
            FROM conversations
        """)
        time_range = cursor.fetchone()
        
        return {
            'total_messages': total_messages,
            'role_distribution': role_distribution,
            'earliest_message': time_range['earliest'],
            'latest_message': time_range['latest'],
            'projects': self.get_project_summary()
        }

def main():
    """CLI interface for conversation insights"""
    import argparse
    
    parser = argparse.ArgumentParser(description="Extract insights from Claude conversations")
    parser.add_argument('--hours', type=int, default=24, 
                       help='Hours to look back (default: 24)')
    parser.add_argument('--search', type=str, help='Search for specific content')
    parser.add_argument('--stats', action='store_true', help='Show conversation statistics')
    parser.add_argument('--json', action='store_true', help='Output as JSON')
    
    args = parser.parse_args()
    
    try:
        with ConversationInsights() as insights:
            if args.search:
                results = insights.search_conversations(args.search)
                if args.json:
                    print(json.dumps(results, indent=2))
                else:
                    for i, result in enumerate(results):
                        print(f"\n{i+1}. {result['project']} - {result['timestamp']}")
                        print(f"   {result['role']}: {result['snippet']}")
            
            elif args.stats:
                stats = insights.get_conversation_stats()
                if args.json:
                    print(json.dumps(stats, indent=2))
                else:
                    print(f"Total messages: {stats['total_messages']}")
                    print(f"Time range: {stats['earliest_message']} to {stats['latest_message']}")
                    print("\nRole distribution:")
                    for role, count in stats['role_distribution'].items():
                        print(f"  {role}: {count}")
                    print("\nProjects:")
                    for project, count in stats['projects'].items():
                        print(f"  {project}: {count} messages")
            
            else:
                # Get recent insights
                recent = insights.get_recent_insights(hours=args.hours)
                if args.json:
                    print(json.dumps(recent, indent=2))
                else:
                    print(f"Recent activity (last {args.hours} hours):")
                    print(f"Messages analyzed: {recent['message_count']}")
                    print(f"Last activity: {recent['last_activity']}")
                    
                    if recent['topics']:
                        print("\nTopics discussed:")
                        for topic in recent['topics']:
                            print(f"  • {topic}")
                    
                    if recent['decisions']:
                        print("\nDecisions made:")
                        for decision in recent['decisions']:
                            print(f"  • {decision}")
                    
                    if recent['tasks']:
                        print("\nTasks identified:")
                        for task in recent['tasks'][:3]:
                            print(f"  • {task[:80]}...")
                    
                    if recent['questions']:
                        print("\nQuestions asked:")
                        for question in recent['questions']:
                            print(f"  • {question}")
                    
                    if recent['code_patterns']:
                        print("\nCode patterns:")
                        for pattern in recent['code_patterns']:
                            print(f"  • {pattern}")
                            
    except FileNotFoundError:
        print("No conversation database found. Run 'mira index-conversations' first.")
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()