#!/usr/bin/env python3
"""
AI News Digest Bot - Main Runner
Orchestrates the entire news digest pipeline: RSS aggregation, AI filtering, and compilation.
"""

import os
import sys
import json
import logging
import argparse
from datetime import datetime
from pathlib import Path

# Add the scripts directory to Python path for imports
script_dir = Path(__file__).parent
sys.path.insert(0, str(script_dir))

from rss_aggregator import RSSAggregator
from ai_filter import AIFilter
from digest_compiler import DigestCompiler

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class AINewsDigestBot:
    def __init__(self, config: dict = None):
        """Initialize the AI News Digest Bot."""
        self.config = config or self.load_default_config()
        self.skill_dir = Path(__file__).parent.parent
        self.cache_dir = self.skill_dir / "cache"
        self.output_dir = self.skill_dir / "output"
        
        # Create directories if they don't exist
        self.cache_dir.mkdir(exist_ok=True)
        self.output_dir.mkdir(exist_ok=True)
        
        # Initialize components
        sources_file = self.skill_dir / "references" / "sources.json"
        self.aggregator = RSSAggregator(str(sources_file), str(self.cache_dir))
        self.ai_filter = AIFilter(
            api_key=self.config.get('openai_api_key'),
            model=self.config.get('openai_model', 'gpt-3.5-turbo')
        )
        self.compiler = DigestCompiler()
        
    def load_default_config(self) -> dict:
        """Load default configuration with environment variable fallbacks."""
        return {
            'max_age_hours': int(os.getenv('DIGEST_MAX_AGE_HOURS', '24')),
            'min_score': float(os.getenv('DIGEST_MIN_SCORE', '6.0')),
            'max_articles': int(os.getenv('DIGEST_MAX_ARTICLES', '50')),
            'top_stories_count': int(os.getenv('DIGEST_TOP_STORIES', '5')),
            'openai_api_key': os.getenv('OPENAI_API_KEY'),
            'openai_model': os.getenv('OPENAI_MODEL', 'gpt-3.5-turbo'),
            'output_formats': os.getenv('DIGEST_FORMATS', 'discord,telegram').split(','),
            'discord_webhook': os.getenv('DISCORD_WEBHOOK'),
            'telegram_bot_token': os.getenv('TELEGRAM_BOT_TOKEN'),
            'telegram_chat_id': os.getenv('TELEGRAM_CHAT_ID'),
        }
    
    def run_full_pipeline(self, output_formats: list = None) -> dict:
        """Run the complete news digest pipeline."""
        logger.info("Starting AI News Digest pipeline...")
        
        try:
            # Step 1: Aggregate RSS feeds
            logger.info("Step 1: Aggregating RSS feeds...")
            articles = self.aggregator.fetch_all_feeds(
                max_age_hours=self.config['max_age_hours']
            )
            
            if not articles:
                logger.warning("No articles found. Exiting.")
                return {'status': 'error', 'message': 'No articles found'}
            
            logger.info(f"Found {len(articles)} articles")
            
            # Save raw articles
            raw_file = self.cache_dir / f"raw_articles_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
            self.aggregator.save_cache(articles, raw_file.name)
            
            # Step 2: Filter with AI
            logger.info("Step 2: Filtering articles with AI...")
            top_articles = self.ai_filter.get_top_stories(
                articles, 
                count=self.config['top_stories_count']
            )
            
            if not top_articles:
                logger.warning("No articles passed filtering. Lowering standards...")
                # Fallback: get top articles with lower threshold
                all_scored = self.ai_filter.filter_articles(
                    articles, 
                    min_score=4.0, 
                    max_articles=10
                )
                top_articles = all_scored[:self.config['top_stories_count']]
            
            logger.info(f"Selected {len(top_articles)} top articles")
            
            # Save filtered articles
            filtered_file = self.cache_dir / f"filtered_articles_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
            with open(filtered_file, 'w') as f:
                json.dump({
                    'filtered_at': datetime.now().isoformat(),
                    'count': len(top_articles),
                    'config': self.config,
                    'articles': top_articles
                }, f, indent=2)
            
            # Step 3: Compile digests
            logger.info("Step 3: Compiling digests...")
            formats = output_formats or self.config.get('output_formats', ['discord'])
            compiled_digests = {}
            
            for format_type in formats:
                logger.info(f"Compiling {format_type} format...")
                digest = self.compiler.compile_digest(
                    top_articles, 
                    format_type=format_type.strip()
                )
                
                # Save digest
                digest_file = self.output_dir / f"digest_{format_type}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
                
                if format_type.lower() == 'email':
                    digest_file = digest_file.with_suffix('.html')
                elif format_type.lower() == 'markdown':
                    digest_file = digest_file.with_suffix('.md')
                else:
                    digest_file = digest_file.with_suffix('.txt')
                
                with open(digest_file, 'w', encoding='utf-8') as f:
                    f.write(digest)
                
                compiled_digests[format_type] = {
                    'content': digest,
                    'file': str(digest_file),
                    'length': len(digest)
                }
                
                logger.info(f"Saved {format_type} digest to {digest_file}")
            
            # Step 4: Deliver (if configured)
            delivery_results = {}
            if self.config.get('discord_webhook') and 'discord' in compiled_digests:
                delivery_results['discord'] = self.deliver_discord(
                    compiled_digests['discord']['content']
                )
            
            if (self.config.get('telegram_bot_token') and 
                self.config.get('telegram_chat_id') and 
                'telegram' in compiled_digests):
                delivery_results['telegram'] = self.deliver_telegram(
                    compiled_digests['telegram']['content']
                )
            
            # Final result
            result = {
                'status': 'success',
                'timestamp': datetime.now().isoformat(),
                'stats': {
                    'raw_articles': len(articles),
                    'filtered_articles': len(top_articles),
                    'avg_score': sum(a.get('ai_score', {}).get('overall', 0) for a in top_articles) / len(top_articles) if top_articles else 0
                },
                'files': {
                    'raw': str(raw_file),
                    'filtered': str(filtered_file),
                    'digests': {k: v['file'] for k, v in compiled_digests.items()}
                },
                'digests': compiled_digests,
                'delivery': delivery_results
            }
            
            logger.info(f"Pipeline completed successfully! Processed {len(articles)} articles into {len(top_articles)} top stories.")
            return result
            
        except Exception as e:
            logger.error(f"Pipeline failed: {e}", exc_info=True)
            return {
                'status': 'error',
                'message': str(e),
                'timestamp': datetime.now().isoformat()
            }
    
    def deliver_discord(self, digest_content: str) -> dict:
        """Deliver digest to Discord via webhook."""
        try:
            import requests
            
            webhook_url = self.config.get('discord_webhook')
            if not webhook_url:
                return {'status': 'skipped', 'reason': 'No webhook configured'}
            
            # Split content if it's too long for Discord (2000 char limit)
            chunks = self.split_content(digest_content, 2000)
            
            results = []
            for i, chunk in enumerate(chunks):
                payload = {'content': chunk}
                
                response = requests.post(webhook_url, json=payload, timeout=30)
                response.raise_for_status()
                
                results.append({
                    'chunk': i + 1,
                    'status': 'sent',
                    'length': len(chunk)
                })
                
                # Small delay between chunks
                if len(chunks) > 1 and i < len(chunks) - 1:
                    import time
                    time.sleep(1)
            
            logger.info(f"Successfully sent {len(chunks)} Discord message(s)")
            return {'status': 'success', 'chunks': len(chunks), 'results': results}
            
        except Exception as e:
            logger.error(f"Discord delivery failed: {e}")
            return {'status': 'error', 'message': str(e)}
    
    def deliver_telegram(self, digest_content: str) -> dict:
        """Deliver digest to Telegram via bot API."""
        try:
            import requests
            
            bot_token = self.config.get('telegram_bot_token')
            chat_id = self.config.get('telegram_chat_id')
            
            if not bot_token or not chat_id:
                return {'status': 'skipped', 'reason': 'Bot token or chat ID not configured'}
            
            # Split content if it's too long for Telegram (4096 char limit)
            chunks = self.split_content(digest_content, 4096)
            
            results = []
            for i, chunk in enumerate(chunks):
                url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
                payload = {
                    'chat_id': chat_id,
                    'text': chunk,
                    'parse_mode': 'Markdown',
                    'disable_web_page_preview': True
                }
                
                response = requests.post(url, json=payload, timeout=30)
                response.raise_for_status()
                
                results.append({
                    'chunk': i + 1,
                    'status': 'sent',
                    'length': len(chunk),
                    'message_id': response.json().get('result', {}).get('message_id')
                })
                
                # Small delay between chunks
                if len(chunks) > 1 and i < len(chunks) - 1:
                    import time
                    time.sleep(1)
            
            logger.info(f"Successfully sent {len(chunks)} Telegram message(s)")
            return {'status': 'success', 'chunks': len(chunks), 'results': results}
            
        except Exception as e:
            logger.error(f"Telegram delivery failed: {e}")
            return {'status': 'error', 'message': str(e)}
    
    def split_content(self, content: str, max_length: int) -> list:
        """Split content into chunks that fit platform limits."""
        if len(content) <= max_length:
            return [content]
        
        chunks = []
        current_chunk = ""
        
        for line in content.split('\n'):
            if len(current_chunk) + len(line) + 1 <= max_length:
                current_chunk += line + '\n'
            else:
                if current_chunk:
                    chunks.append(current_chunk.rstrip())
                current_chunk = line + '\n'
        
        if current_chunk:
            chunks.append(current_chunk.rstrip())
        
        return chunks
    
    def get_latest_digest(self, format_type: str = 'discord') -> str:
        """Get the most recent digest file for the specified format."""
        pattern = f"digest_{format_type}_*.txt"
        if format_type.lower() == 'email':
            pattern = f"digest_{format_type}_*.html"
        elif format_type.lower() == 'markdown':
            pattern = f"digest_{format_type}_*.md"
        
        files = list(self.output_dir.glob(pattern))
        if not files:
            return None
        
        latest_file = max(files, key=lambda f: f.stat().st_mtime)
        with open(latest_file, 'r', encoding='utf-8') as f:
            return f.read()

def main():
    """Main CLI interface."""
    parser = argparse.ArgumentParser(description='AI News Digest Bot - Generate AI news digests')
    
    subparsers = parser.add_subparsers(dest='command', help='Available commands')
    
    # Run command
    run_parser = subparsers.add_parser('run', help='Run the full digest pipeline')
    run_parser.add_argument('--formats', nargs='+', choices=['discord', 'telegram', 'email', 'markdown', 'text'],
                           default=['discord'], help='Output formats to generate')
    run_parser.add_argument('--no-delivery', action='store_true', help='Skip automatic delivery')
    run_parser.add_argument('--config', help='Config file path (JSON)')
    
    # Test command
    test_parser = subparsers.add_parser('test', help='Test individual components')
    test_parser.add_argument('component', choices=['rss', 'filter', 'compile'], help='Component to test')
    test_parser.add_argument('--limit', type=int, default=3, help='Limit number of items for testing')
    
    # Deliver command
    deliver_parser = subparsers.add_parser('deliver', help='Deliver an existing digest')
    deliver_parser.add_argument('platform', choices=['discord', 'telegram'], help='Platform to deliver to')
    deliver_parser.add_argument('--file', help='Digest file to deliver (uses latest if not specified)')
    
    # Status command
    subparsers.add_parser('status', help='Show status and recent digests')
    
    args = parser.parse_args()
    
    # Load config if specified
    config = None
    if hasattr(args, 'config') and args.config:
        try:
            with open(args.config, 'r') as f:
                config = json.load(f)
        except Exception as e:
            print(f"Error loading config: {e}")
            sys.exit(1)
    
    # Initialize bot
    bot = AINewsDigestBot(config)
    
    if args.command == 'run':
        result = bot.run_full_pipeline(args.formats)
        
        if result['status'] == 'success':
            print("✅ Digest pipeline completed successfully!")
            print(f"📊 Processed {result['stats']['raw_articles']} articles → {result['stats']['filtered_articles']} top stories")
            print(f"⭐ Average score: {result['stats']['avg_score']:.1f}/10")
            
            for format_type, file_path in result['files']['digests'].items():
                print(f"📄 {format_type.title()}: {file_path}")
            
            if result.get('delivery'):
                print("\n📤 Delivery results:")
                for platform, result_data in result['delivery'].items():
                    if result_data['status'] == 'success':
                        print(f"  ✅ {platform.title()}: Sent {result_data.get('chunks', 1)} message(s)")
                    else:
                        print(f"  ❌ {platform.title()}: {result_data.get('message', 'Failed')}")
        else:
            print(f"❌ Pipeline failed: {result['message']}")
            sys.exit(1)
    
    elif args.command == 'test':
        if args.component == 'rss':
            print("🔍 Testing RSS aggregation...")
            articles = bot.aggregator.fetch_all_feeds(max_age_hours=24)
            print(f"Found {len(articles)} articles from {len(bot.aggregator.sources)} sources")
            
            # Show sample articles
            for i, article in enumerate(articles[:args.limit]):
                print(f"\n{i+1}. {article.get('title', 'No title')}")
                print(f"   Source: {article.get('source', {}).get('name', 'Unknown')}")
                print(f"   Link: {article.get('link', 'No link')}")
        
        elif args.component == 'filter':
            # Need some test articles
            print("🧠 Testing AI filtering...")
            print("Note: This requires articles. Run 'test rss' first or provide a cache file.")
            
        elif args.component == 'compile':
            print("📝 Testing digest compilation...")
            # Create sample articles for testing
            sample_articles = [{
                'title': 'Sample AI News Article',
                'description': 'This is a sample article for testing the digest compiler.',
                'link': 'https://example.com',
                'source': {'name': 'Test Source', 'category': 'research'},
                'ai_score': {'overall': 8.5, 'relevance': 9, 'importance': 8, 'category': 'research'}
            }]
            
            digest = bot.compiler.compile_digest(sample_articles, 'discord')
            print("Sample Discord digest:")
            print("-" * 50)
            print(digest)
    
    elif args.command == 'deliver':
        print(f"📤 Delivering to {args.platform}...")
        
        if args.file:
            with open(args.file, 'r', encoding='utf-8') as f:
                content = f.read()
        else:
            content = bot.get_latest_digest(args.platform)
            if not content:
                print(f"❌ No recent {args.platform} digest found")
                sys.exit(1)
        
        if args.platform == 'discord':
            result = bot.deliver_discord(content)
        elif args.platform == 'telegram':
            result = bot.deliver_telegram(content)
        
        if result['status'] == 'success':
            print(f"✅ Successfully delivered to {args.platform}")
        else:
            print(f"❌ Delivery failed: {result.get('message', 'Unknown error')}")
    
    elif args.command == 'status':
        print("📊 AI News Digest Bot Status")
        print("=" * 40)
        
        # Check cache directory
        cache_files = list(bot.cache_dir.glob('*.json'))
        print(f"📁 Cache files: {len(cache_files)}")
        
        # Check output directory  
        output_files = list(bot.output_dir.glob('digest_*'))
        print(f"📄 Digest files: {len(output_files)}")
        
        if output_files:
            latest = max(output_files, key=lambda f: f.stat().st_mtime)
            mod_time = datetime.fromtimestamp(latest.stat().st_mtime)
            print(f"🕒 Latest digest: {latest.name} ({mod_time.strftime('%Y-%m-%d %H:%M')})")
        
        # Check configuration
        print(f"\n⚙️  Configuration:")
        print(f"  OpenAI API: {'✅ Configured' if bot.config.get('openai_api_key') else '❌ Missing'}")
        print(f"  Discord: {'✅ Configured' if bot.config.get('discord_webhook') else '❌ Missing'}")
        print(f"  Telegram: {'✅ Configured' if bot.config.get('telegram_bot_token') and bot.config.get('telegram_chat_id') else '❌ Missing'}")
    
    else:
        parser.print_help()

if __name__ == "__main__":
    main()