#!/usr/bin/env python3
"""
Digest Compiler for AI News Digest Bot
Compiles filtered articles into formatted digests for various platforms.
"""

import json
import logging
from datetime import datetime
from typing import List, Dict, Any, Optional
import textwrap
import re

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

class DigestCompiler:
    def __init__(self):
        """Initialize the digest compiler."""
        self.emoji_map = {
            'research': '🔬',
            'product': '🚀', 
            'funding': '💰',
            'partnership': '🤝',
            'opinion': '💭',
            'breakthrough': '⚡',
            'regulatory': '⚖️',
            'ethics': '🤔',
            'safety': '🛡️',
            'opensource': '🌐',
            'other': '📰'
        }
    
    def compile_digest(self, articles: List[Dict[str, Any]], 
                      format_type: str = "discord", 
                      title: str = None) -> str:
        """Compile articles into a formatted digest."""
        if not articles:
            return "No articles found for today's digest."
        
        title = title or f"🤖 AI News Digest - {datetime.now().strftime('%B %d, %Y')}"
        
        if format_type.lower() == "discord":
            return self.format_discord(articles, title)
        elif format_type.lower() == "telegram":
            return self.format_telegram(articles, title)
        elif format_type.lower() == "email":
            return self.format_email(articles, title)
        elif format_type.lower() == "markdown":
            return self.format_markdown(articles, title)
        else:
            return self.format_text(articles, title)
    
    def format_discord(self, articles: List[Dict[str, Any]], title: str) -> str:
        """Format digest for Discord (supports embeds and markdown)."""
        digest = f"## {title}\n\n"
        
        # Add summary stats
        total_articles = len(articles)
        avg_score = sum(article.get('ai_score', {}).get('overall', 0) for article in articles) / len(articles)
        digest += f"📊 **{total_articles} top stories** • Average quality: {avg_score:.1f}/10\n\n"
        
        # Group articles by category
        categories = {}
        for article in articles:
            category = article.get('ai_score', {}).get('category', 'other')
            if category not in categories:
                categories[category] = []
            categories[category].append(article)
        
        # Sort categories by importance
        category_order = ['research', 'product', 'funding', 'partnership', 'breakthrough', 'other']
        
        for category in category_order:
            if category not in categories:
                continue
                
            emoji = self.emoji_map.get(category, '📰')
            digest += f"### {emoji} {category.title()}\n\n"
            
            for article in categories[category][:3]:  # Limit to top 3 per category
                digest += self.format_article_discord(article)
                digest += "\n"
        
        # Add footer
        digest += "\n---\n"
        digest += f"*Generated at {datetime.now().strftime('%H:%M UTC')} • Powered by AI News Digest Bot*\n"
        
        return digest
    
    def format_telegram(self, articles: List[Dict[str, Any]], title: str) -> str:
        """Format digest for Telegram (supports basic markdown)."""
        digest = f"*{title}*\n\n"
        
        # Add summary
        digest += f"📊 {len(articles)} top AI stories today\n\n"
        
        for i, article in enumerate(articles[:5], 1):  # Top 5 for Telegram
            emoji = self.get_article_emoji(article)
            title = self.truncate_text(article.get('title', 'Untitled'), 80)
            score = article.get('ai_score', {}).get('overall', 0)
            source = article.get('source', {}).get('name', 'Unknown')
            link = article.get('link', '')
            
            digest += f"{emoji} *{i}. {title}*\n"
            digest += f"📈 Score: {score:.1f}/10 | 📰 {source}\n"
            
            # Add description if available
            description = article.get('description', '')
            if description:
                clean_desc = self.clean_text(description)
                short_desc = self.truncate_text(clean_desc, 150)
                digest += f"{short_desc}\n"
            
            # Add link
            if link:
                digest += f"🔗 [Read more]({link})\n"
            
            digest += "\n"
        
        digest += f"_Generated at {datetime.now().strftime('%H:%M UTC')}_"
        
        return digest
    
    def format_email(self, articles: List[Dict[str, Any]], title: str) -> str:
        """Format digest for email (HTML format)."""
        html = f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{title}</title>
    <style>
        body {{ font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }}
        .header {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; }}
        .article {{ border: 1px solid #ddd; border-radius: 8px; padding: 15px; margin-bottom: 15px; }}
        .article-title {{ font-size: 18px; font-weight: bold; margin-bottom: 10px; color: #333; }}
        .article-meta {{ font-size: 12px; color: #666; margin-bottom: 10px; }}
        .article-desc {{ line-height: 1.6; color: #444; }}
        .score {{ background: #4CAF50; color: white; padding: 3px 8px; border-radius: 12px; font-size: 11px; }}
        .footer {{ text-align: center; color: #888; font-size: 12px; margin-top: 30px; }}
        a {{ color: #667eea; text-decoration: none; }}
        a:hover {{ text-decoration: underline; }}
    </style>
</head>
<body>
    <div class="header">
        <h1>🤖 {title}</h1>
        <p>Your daily dose of AI news, curated by AI</p>
    </div>
"""
        
        for i, article in enumerate(articles, 1):
            title_text = article.get('title', 'Untitled')
            description = self.clean_text(article.get('description', ''))
            source = article.get('source', {}).get('name', 'Unknown')
            link = article.get('link', '')
            score = article.get('ai_score', {}).get('overall', 0)
            
            html += f"""
    <div class="article">
        <div class="article-title">
            {i}. <a href="{link}" target="_blank">{title_text}</a>
        </div>
        <div class="article-meta">
            📰 {source} • <span class="score">{score:.1f}/10</span>
        </div>
        <div class="article-desc">
            {self.truncate_text(description, 300)}
        </div>
    </div>
"""
        
        html += f"""
    <div class="footer">
        <p>Generated at {datetime.now().strftime('%B %d, %Y at %H:%M UTC')}</p>
        <p>Powered by AI News Digest Bot</p>
    </div>
</body>
</html>
"""
        return html
    
    def format_markdown(self, articles: List[Dict[str, Any]], title: str) -> str:
        """Format digest as clean markdown."""
        markdown = f"# {title}\n\n"
        markdown += f"*{len(articles)} top AI stories for {datetime.now().strftime('%B %d, %Y')}*\n\n"
        
        for i, article in enumerate(articles, 1):
            title_text = article.get('title', 'Untitled')
            description = self.clean_text(article.get('description', ''))
            source = article.get('source', {}).get('name', 'Unknown')
            link = article.get('link', '')
            score = article.get('ai_score', {}).get('overall', 0)
            
            markdown += f"## {i}. {title_text}\n\n"
            markdown += f"**Source:** {source} | **Score:** {score:.1f}/10\n\n"
            
            if description:
                markdown += f"{self.truncate_text(description, 300)}\n\n"
            
            if link:
                markdown += f"[Read full article]({link})\n\n"
            
            markdown += "---\n\n"
        
        markdown += f"*Generated on {datetime.now().strftime('%B %d, %Y at %H:%M UTC')} by AI News Digest Bot*\n"
        
        return markdown
    
    def format_text(self, articles: List[Dict[str, Any]], title: str) -> str:
        """Format digest as plain text."""
        text = f"{title}\n"
        text += "=" * len(title) + "\n\n"
        
        for i, article in enumerate(articles, 1):
            title_text = article.get('title', 'Untitled')
            description = self.clean_text(article.get('description', ''))
            source = article.get('source', {}).get('name', 'Unknown')
            link = article.get('link', '')
            score = article.get('ai_score', {}).get('overall', 0)
            
            text += f"{i}. {title_text}\n"
            text += f"Source: {source} | Score: {score:.1f}/10\n"
            
            if description:
                wrapped_desc = textwrap.fill(self.truncate_text(description, 300), width=80)
                text += f"{wrapped_desc}\n"
            
            if link:
                text += f"Link: {link}\n"
            
            text += "-" * 80 + "\n\n"
        
        text += f"Generated on {datetime.now().strftime('%B %d, %Y at %H:%M UTC')}\n"
        text += "Powered by AI News Digest Bot\n"
        
        return text
    
    def format_article_discord(self, article: Dict[str, Any]) -> str:
        """Format a single article for Discord."""
        emoji = self.get_article_emoji(article)
        title = article.get('title', 'Untitled')
        source = article.get('source', {}).get('name', 'Unknown')
        score = article.get('ai_score', {}).get('overall', 0)
        link = article.get('link', '')
        
        formatted = f"{emoji} **[{title}]({link})**\n"
        formatted += f"📊 {score:.1f}/10 • 📰 {source}\n"
        
        # Add description if available
        description = article.get('description', '')
        if description:
            clean_desc = self.clean_text(description)
            short_desc = self.truncate_text(clean_desc, 200)
            formatted += f"*{short_desc}*\n"
        
        return formatted
    
    def get_article_emoji(self, article: Dict[str, Any]) -> str:
        """Get appropriate emoji for article based on category and content."""
        category = article.get('ai_score', {}).get('category', 'other')
        
        # Check for specific keywords in title for more specific emojis
        title = article.get('title', '').lower()
        
        if any(word in title for word in ['gpt', 'claude', 'gemini', 'llm', 'language model']):
            return '🧠'
        elif any(word in title for word in ['funding', 'investment', 'billion', 'million']):
            return '💰'
        elif any(word in title for word in ['breakthrough', 'achieves', 'first time']):
            return '⚡'
        elif any(word in title for word in ['regulation', 'law', 'government']):
            return '⚖️'
        else:
            return self.emoji_map.get(category, '📰')
    
    def clean_text(self, text: str) -> str:
        """Clean text by removing HTML tags and normalizing whitespace."""
        if not text:
            return ""
        
        # Remove HTML tags
        text = re.sub(r'<[^>]+>', '', text)
        
        # Normalize whitespace
        text = re.sub(r'\s+', ' ', text)
        
        # Remove extra punctuation
        text = re.sub(r'\.{2,}', '...', text)
        
        return text.strip()
    
    def truncate_text(self, text: str, max_length: int) -> str:
        """Truncate text to specified length with ellipsis."""
        if not text or len(text) <= max_length:
            return text
        
        # Try to break at word boundaries
        truncated = text[:max_length]
        if ' ' in truncated:
            truncated = truncated.rsplit(' ', 1)[0]
        
        return truncated + "..."
    
    def create_summary_stats(self, articles: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Create summary statistics for the digest."""
        if not articles:
            return {}
        
        stats = {
            'total_articles': len(articles),
            'avg_score': sum(article.get('ai_score', {}).get('overall', 0) for article in articles) / len(articles),
            'top_sources': {},
            'categories': {},
            'score_distribution': {'high': 0, 'medium': 0, 'low': 0}
        }
        
        for article in articles:
            # Source statistics
            source = article.get('source', {}).get('name', 'Unknown')
            stats['top_sources'][source] = stats['top_sources'].get(source, 0) + 1
            
            # Category statistics
            category = article.get('ai_score', {}).get('category', 'other')
            stats['categories'][category] = stats['categories'].get(category, 0) + 1
            
            # Score distribution
            score = article.get('ai_score', {}).get('overall', 0)
            if score >= 8:
                stats['score_distribution']['high'] += 1
            elif score >= 6:
                stats['score_distribution']['medium'] += 1
            else:
                stats['score_distribution']['low'] += 1
        
        return stats

def main():
    """Main function for command-line usage."""
    import argparse
    
    parser = argparse.ArgumentParser(description='Compile AI news digest from filtered articles')
    parser.add_argument('input', help='Input JSON file with filtered articles')
    parser.add_argument('--format', choices=['discord', 'telegram', 'email', 'markdown', 'text'], 
                       default='markdown', help='Output format')
    parser.add_argument('--output', help='Output file path')
    parser.add_argument('--title', help='Custom title for the digest')
    
    args = parser.parse_args()
    
    # Load articles
    try:
        with open(args.input, 'r') as f:
            data = json.load(f)
            articles = data.get('articles', [])
    except FileNotFoundError:
        print(f"Error: Input file not found: {args.input}")
        return
    except json.JSONDecodeError as e:
        print(f"Error parsing input file: {e}")
        return
    
    # Compile digest
    compiler = DigestCompiler()
    digest = compiler.compile_digest(articles, args.format, args.title)
    
    # Save output
    if args.output:
        try:
            with open(args.output, 'w', encoding='utf-8') as f:
                f.write(digest)
            print(f"Digest saved to: {args.output}")
        except Exception as e:
            print(f"Error saving digest: {e}")
    else:
        print(digest)
    
    # Print stats
    stats = compiler.create_summary_stats(articles)
    print(f"\nDigest Stats:")
    print(f"- {stats.get('total_articles', 0)} articles")
    print(f"- Average score: {stats.get('avg_score', 0):.1f}/10")
    print(f"- Top category: {max(stats.get('categories', {}).items(), key=lambda x: x[1])[0] if stats.get('categories') else 'None'}")

if __name__ == "__main__":
    main()