"""
Intelligence Aggregator

Aggregates content analysis results into daily intelligence JSON reports
with strategic insights, trends, and competitive analysis.
"""

import json
import logging
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Any, Optional
from collections import Counter, defaultdict
from dataclasses import asdict, dataclass, field

from .claude_analyzer import ClaudeHaikuAnalyzer, ContentAnalysisResult
from .engagement_analyzer import EngagementAnalyzer, EngagementMetrics, TrendingContent
from .keyword_extractor import KeywordExtractor, KeywordAnalysis, SEOOpportunity


@dataclass
class AnalysisResult:
    """Base class for content analysis results"""
    content_id: str
    title: str
    content: str
    source: str
    analyzed_at: datetime
    claude_analysis: Optional[Any] = None
    engagement_metrics: Dict[str, Any] = field(default_factory=dict)
    keywords: List[str] = field(default_factory=list)
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert to dictionary for JSON serialization"""
        return {
            'content_id': self.content_id,
            'title': self.title,
            'content': self.content,
            'source': self.source,
            'analyzed_at': self.analyzed_at.isoformat(),
            'claude_analysis': self.claude_analysis,
            'engagement_metrics': self.engagement_metrics,
            'keywords': self.keywords,
            'metadata': self.metadata
        }


class IntelligenceAggregator:
    """Aggregates content analysis into comprehensive intelligence reports"""
    
    def __init__(self, data_dir: Path):
        self.data_dir = data_dir
        self.intelligence_dir = data_dir / "intelligence"
        self.intelligence_dir.mkdir(parents=True, exist_ok=True)
        
        # Create subdirectories
        (self.intelligence_dir / "daily").mkdir(exist_ok=True)
        (self.intelligence_dir / "weekly").mkdir(exist_ok=True)
        (self.intelligence_dir / "monthly").mkdir(exist_ok=True)
        
        self.logger = logging.getLogger(__name__)
        
        # Initialize analyzers
        try:
            self.claude_analyzer = ClaudeHaikuAnalyzer()
            self.claude_enabled = True
        except Exception as e:
            self.logger.warning(f"Claude analyzer disabled: {e}")
            self.claude_analyzer = None
            self.claude_enabled = False
            
        self.engagement_analyzer = EngagementAnalyzer()
        self.keyword_extractor = KeywordExtractor()

    def generate_daily_intelligence(self, date: Optional[datetime] = None) -> Dict[str, Any]:
        """Generate daily intelligence report"""
        
        if date is None:
            date = datetime.now()
        
        date_str = date.strftime('%Y-%m-%d')
        
        try:
            # Load HKIA content for the day
            hkia_content = self._load_hkia_content(date)
            
            # Load competitor content (if available)
            competitor_content = self._load_competitor_content(date)
            
            # Analyze HKIA content
            hkia_analysis = self._analyze_hkia_content(hkia_content)
            
            # Analyze competitor content
            competitor_analysis = self._analyze_competitor_content(competitor_content)
            
            # Generate strategic insights
            strategic_insights = self._generate_strategic_insights(hkia_analysis, competitor_analysis)
            
            # Compile intelligence report
            intelligence_report = {
                "report_date": date_str,
                "generated_at": datetime.now().isoformat(),
                "hkia_analysis": hkia_analysis,
                "competitor_analysis": competitor_analysis,
                "strategic_insights": strategic_insights,
                "meta": {
                    "total_hkia_items": len(hkia_content),
                    "total_competitor_items": sum(len(items) for items in competitor_content.values()),
                    "analysis_version": "1.0"
                }
            }
            
            # Save report
            report_file = self.intelligence_dir / "daily" / f"hkia_intelligence_{date_str}.json"
            with open(report_file, 'w', encoding='utf-8') as f:
                json.dump(intelligence_report, f, indent=2, ensure_ascii=False)
            
            self.logger.info(f"Generated daily intelligence report: {report_file}")
            return intelligence_report
            
        except Exception as e:
            self.logger.error(f"Error generating daily intelligence for {date_str}: {e}")
            raise

    def generate_weekly_intelligence(self, end_date: Optional[datetime] = None) -> Dict[str, Any]:
        """Generate weekly intelligence summary"""
        
        if end_date is None:
            end_date = datetime.now()
        
        start_date = end_date - timedelta(days=6)  # 7-day period
        week_str = end_date.strftime('%Y-%m-%d')
        
        # Load daily reports for the week
        daily_reports = []
        for i in range(7):
            report_date = start_date + timedelta(days=i)
            daily_report = self._load_daily_intelligence(report_date)
            if daily_report:
                daily_reports.append(daily_report)
        
        # Aggregate weekly insights
        weekly_intelligence = {
            "report_week_ending": week_str,
            "generated_at": datetime.now().isoformat(),
            "period_summary": self._create_weekly_summary(daily_reports),
            "trending_topics": self._identify_weekly_trends(daily_reports),
            "competitor_movements": self._analyze_weekly_competitor_activity(daily_reports),
            "content_performance": self._analyze_weekly_performance(daily_reports),
            "strategic_recommendations": self._generate_weekly_recommendations(daily_reports)
        }
        
        # Save weekly report
        report_file = self.intelligence_dir / "weekly" / f"hkia_weekly_intelligence_{week_str}.json"
        with open(report_file, 'w', encoding='utf-8') as f:
            json.dump(weekly_intelligence, f, indent=2, ensure_ascii=False)
        
        return weekly_intelligence

    def _load_hkia_content(self, date: datetime) -> List[Dict[str, Any]]:
        """Load HKIA content from markdown current directory"""
        
        content_items = []
        current_dir = self.data_dir / "markdown_current"
        
        if not current_dir.exists():
            self.logger.warning(f"HKIA content directory not found: {current_dir}")
            return []
        
        # Load content from markdown files
        for md_file in current_dir.glob("*.md"):
            try:
                # Parse markdown file for content items
                items = self._parse_markdown_file(md_file)
                content_items.extend(items)
            except Exception as e:
                self.logger.error(f"Error parsing {md_file}: {e}")
        
        return content_items

    def _load_competitor_content(self, date: datetime) -> Dict[str, List[Dict[str, Any]]]:
        """Load competitor content (placeholder for future implementation)"""
        
        # This will be implemented in Phase 2
        # For now, return empty dict
        return {}

    def _analyze_hkia_content(self, content_items: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze HKIA content comprehensively"""
        
        if not content_items:
            return {
                "content_classified": 0,
                "topic_distribution": {},
                "engagement_summary": {},
                "trending_keywords": [],
                "content_gaps": []
            }
        
        # Content classification
        content_analyses = []
        if self.claude_enabled:
            for item in content_items:
                try:
                    analysis = self.claude_analyzer.analyze_content(item)
                    content_analyses.append(analysis)
                except Exception as e:
                    self.logger.error(f"Error analyzing content {item.get('id')}: {e}")
        else:
            self.logger.info("Claude analysis skipped - API key not available")
        
        # Topic distribution analysis
        topic_distribution = self._calculate_topic_distribution(content_analyses)
        
        # Engagement analysis by source
        engagement_summary = self._analyze_engagement_by_source(content_items)
        
        # Keyword analysis
        trending_keywords = self.keyword_extractor.identify_trending_keywords(content_items)
        
        # Content gap identification
        content_gaps = self._identify_content_gaps(content_analyses, topic_distribution)
        
        return {
            "content_classified": len(content_analyses),
            "topic_distribution": topic_distribution,
            "engagement_summary": engagement_summary,
            "trending_keywords": [{"keyword": kw, "frequency": freq} for kw, freq in trending_keywords[:10]],
            "content_gaps": content_gaps,
            "sentiment_overview": self._calculate_sentiment_overview(content_analyses)
        }

    def _analyze_competitor_content(self, competitor_content: Dict[str, List[Dict[str, Any]]]) -> Dict[str, Any]:
        """Analyze competitor content (placeholder for Phase 2)"""
        
        if not competitor_content:
            return {
                "competitors_tracked": 0,
                "new_content_count": 0,
                "trending_topics": [],
                "engagement_leaders": []
            }
        
        # This will be fully implemented in Phase 2
        return {
            "competitors_tracked": len(competitor_content),
            "new_content_count": sum(len(items) for items in competitor_content.values()),
            "trending_topics": [],
            "engagement_leaders": []
        }

    def _generate_strategic_insights(self, hkia_analysis: Dict[str, Any], 
                                   competitor_analysis: Dict[str, Any]) -> Dict[str, Any]:
        """Generate strategic content insights and recommendations"""
        
        insights = {
            "content_opportunities": [],
            "performance_insights": [],
            "competitive_advantages": [],
            "areas_for_improvement": []
        }
        
        # Analyze topic coverage gaps
        topic_dist = hkia_analysis.get("topic_distribution", {})
        low_coverage_topics = [topic for topic, data in topic_dist.items() 
                              if data.get("count", 0) < 2]
        
        if low_coverage_topics:
            insights["content_opportunities"].extend([
                f"Increase coverage of {topic.replace('_', ' ')}" 
                for topic in low_coverage_topics[:3]
            ])
        
        # Analyze engagement patterns
        engagement_summary = hkia_analysis.get("engagement_summary", {})
        for source, metrics in engagement_summary.items():
            if metrics.get("avg_engagement_rate", 0) > 0.03:
                insights["performance_insights"].append(
                    f"{source.title()} shows strong engagement (avg: {metrics.get('avg_engagement_rate', 0):.3f})"
                )
            elif metrics.get("trending_count", 0) > 0:
                insights["performance_insights"].append(
                    f"{source.title()} has {metrics.get('trending_count')} trending items"
                )
        
        # Content improvement suggestions
        sentiment_overview = hkia_analysis.get("sentiment_overview", {})
        if sentiment_overview.get("avg_sentiment", 0) < 0.5:
            insights["areas_for_improvement"].append(
                "Consider more positive, solution-focused content"
            )
        
        # Keyword opportunities
        trending_keywords = hkia_analysis.get("trending_keywords", [])
        if trending_keywords:
            top_keyword = trending_keywords[0]["keyword"]
            insights["content_opportunities"].append(
                f"Expand content around trending keyword: {top_keyword}"
            )
        
        return insights

    def _calculate_topic_distribution(self, analyses: List[ContentAnalysisResult]) -> Dict[str, Any]:
        """Calculate topic distribution across content"""
        
        topic_counts = Counter()
        topic_sentiments = defaultdict(list)
        topic_engagement = defaultdict(list)
        
        for analysis in analyses:
            for topic in analysis.topics:
                topic_counts[topic] += 1
                topic_sentiments[topic].append(analysis.sentiment)
                topic_engagement[topic].append(analysis.engagement_prediction)
        
        distribution = {}
        for topic, count in topic_counts.items():
            distribution[topic] = {
                "count": count,
                "avg_sentiment": sum(topic_sentiments[topic]) / len(topic_sentiments[topic]),
                "avg_engagement_prediction": sum(topic_engagement[topic]) / len(topic_engagement[topic])
            }
        
        return distribution

    def _analyze_engagement_by_source(self, content_items: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze engagement metrics by content source"""
        
        sources = defaultdict(list)
        
        # Group items by source
        for item in content_items:
            source = item.get('source', 'unknown')
            sources[source].append(item)
        
        engagement_summary = {}
        
        for source, items in sources.items():
            try:
                metrics = self.engagement_analyzer.analyze_engagement_metrics(items, source)
                trending = self.engagement_analyzer.identify_trending_content(items, source, 5)
                summary = self.engagement_analyzer.calculate_source_summary(items, source)
                
                engagement_summary[source] = {
                    **summary,
                    "trending_content": [
                        {
                            "title": t.title,
                            "engagement_score": t.engagement_score,
                            "trend_type": t.trend_type
                        } for t in trending
                    ]
                }
            except Exception as e:
                self.logger.error(f"Error analyzing engagement for {source}: {e}")
                engagement_summary[source] = {"error": str(e)}
        
        return engagement_summary

    def _identify_content_gaps(self, analyses: List[ContentAnalysisResult], 
                             topic_distribution: Dict[str, Any]) -> List[str]:
        """Identify content gaps based on analysis"""
        
        gaps = []
        
        # Expected high-value topics for HVAC content
        high_value_topics = [
            'heat_pumps', 'troubleshooting', 'installation', 'maintenance',
            'refrigerants', 'electrical', 'smart_hvac'
        ]
        
        for topic in high_value_topics:
            if topic not in topic_distribution or topic_distribution[topic]["count"] < 2:
                gaps.append(f"Limited coverage of {topic.replace('_', ' ')}")
        
        # Check for difficulty level balance
        difficulties = Counter(analysis.difficulty for analysis in analyses)
        total_content = len(analyses)
        
        if total_content > 0:
            beginner_ratio = difficulties.get('beginner', 0) / total_content
            if beginner_ratio < 0.2:
                gaps.append("Need more beginner-level content")
            
            advanced_ratio = difficulties.get('advanced', 0) / total_content
            if advanced_ratio < 0.15:
                gaps.append("Need more advanced technical content")
        
        return gaps[:5]  # Limit to top 5 gaps

    def _calculate_sentiment_overview(self, analyses: List[ContentAnalysisResult]) -> Dict[str, Any]:
        """Calculate overall sentiment metrics"""
        
        if not analyses:
            return {"avg_sentiment": 0, "sentiment_distribution": {}}
        
        sentiments = [analysis.sentiment for analysis in analyses]
        avg_sentiment = sum(sentiments) / len(sentiments)
        
        # Classify sentiment distribution
        positive = len([s for s in sentiments if s > 0.2])
        neutral = len([s for s in sentiments if -0.2 <= s <= 0.2])
        negative = len([s for s in sentiments if s < -0.2])
        
        return {
            "avg_sentiment": avg_sentiment,
            "sentiment_distribution": {
                "positive": positive,
                "neutral": neutral,
                "negative": negative
            }
        }

    def _parse_markdown_file(self, md_file: Path) -> List[Dict[str, Any]]:
        """Parse markdown file to extract content items"""
        
        content_items = []
        
        try:
            with open(md_file, 'r', encoding='utf-8') as f:
                content = f.read()
            
            # Split into individual content items by markdown headers
            items = content.split('\n# ID: ')
            
            for i, item_content in enumerate(items):
                if i == 0 and not item_content.strip().startswith('# ID: ') and not item_content.strip().startswith('ID: '):
                    continue  # Skip header if present
                
                if not item_content.strip():
                    continue
                
                # For the first item, remove the '# ID: ' prefix if present
                if i == 0 and item_content.strip().startswith('# ID: '):
                    item_content = item_content.strip()[6:]  # Remove '# ID: '
                
                # Parse individual item
                item = self._parse_content_item(item_content, md_file.stem)
                if item:
                    content_items.append(item)
                    
        except Exception as e:
            self.logger.error(f"Error reading markdown file {md_file}: {e}")
        
        return content_items

    def _parse_content_item(self, item_content: str, source_hint: str) -> Optional[Dict[str, Any]]:
        """Parse individual content item from markdown"""
        
        lines = item_content.strip().split('\n')
        item = {"source": self._extract_source_from_filename(source_hint)}
        
        current_field = None
        current_value = []
        
        for line in lines:
            line = line.strip()
            
            if line.startswith('## '):
                # Save previous field
                if current_field and current_value:
                    item[current_field] = '\n'.join(current_value).strip()
                
                # Start new field - handle inline values like "## Views: 16"
                field_line = line[3:].strip()  # Remove "## "
                if ':' in field_line:
                    field_name, field_value = field_line.split(':', 1)
                    field_name = field_name.strip().lower().replace(' ', '_')
                    field_value = field_value.strip()
                    if field_value:
                        # Inline value - save directly
                        item[field_name] = field_value
                        current_field = None
                        current_value = []
                    else:
                        # Multi-line value - will be collected next
                        current_field = field_name
                        current_value = []
                else:
                    # No colon, treat as field name only
                    field_name = field_line.lower().replace(' ', '_')
                    current_field = field_name
                    current_value = []
                
            elif current_field and line:
                current_value.append(line)
            elif not line.startswith('#'):
                # Handle content that's not in a field
                if 'id' not in item and line:
                    item['id'] = line.strip()
        
        # Save last field
        if current_field and current_value:
            item[current_field] = '\n'.join(current_value).strip()
        
        # Extract numeric fields
        self._extract_numeric_fields(item)
        
        return item if item.get('id') else None

    def _extract_source_from_filename(self, filename: str) -> str:
        """Extract source name from filename"""
        
        filename_lower = filename.lower()
        
        if 'youtube' in filename_lower:
            return 'youtube'
        elif 'instagram' in filename_lower:
            return 'instagram'
        elif 'wordpress' in filename_lower:
            return 'wordpress'
        elif 'mailchimp' in filename_lower:
            return 'mailchimp'
        elif 'podcast' in filename_lower:
            return 'podcast'
        elif 'hvacrschool' in filename_lower:
            return 'hvacrschool'
        else:
            return 'unknown'

    def _extract_numeric_fields(self, item: Dict[str, Any]) -> None:
        """Extract and convert numeric fields"""
        
        numeric_fields = ['views', 'likes', 'comments', 'view_count']
        
        for field in numeric_fields:
            if field in item:
                try:
                    # Remove commas and convert to int
                    value = str(item[field]).replace(',', '').strip()
                    item[field] = int(value) if value.isdigit() else 0
                except (ValueError, TypeError):
                    item[field] = 0

    def _load_daily_intelligence(self, date: datetime) -> Optional[Dict[str, Any]]:
        """Load daily intelligence report for a specific date"""
        
        date_str = date.strftime('%Y-%m-%d')
        report_file = self.intelligence_dir / "daily" / f"hkia_intelligence_{date_str}.json"
        
        if report_file.exists():
            try:
                with open(report_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            except Exception as e:
                self.logger.error(f"Error loading daily intelligence for {date_str}: {e}")
        
        return None

    def _create_weekly_summary(self, daily_reports: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Create weekly summary from daily reports"""
        
        # This will be implemented for weekly reporting
        return {
            "days_analyzed": len(daily_reports),
            "total_content_items": sum(r.get("meta", {}).get("total_hkia_items", 0) for r in daily_reports)
        }

    def _identify_weekly_trends(self, daily_reports: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """Identify weekly trending topics"""
        
        # This will be implemented for weekly reporting
        return []

    def _analyze_weekly_competitor_activity(self, daily_reports: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze weekly competitor activity"""
        
        # This will be implemented for weekly reporting
        return {}

    def _analyze_weekly_performance(self, daily_reports: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Analyze weekly content performance"""
        
        # This will be implemented for weekly reporting
        return {}

    def _generate_weekly_recommendations(self, daily_reports: List[Dict[str, Any]]) -> List[str]:
        """Generate weekly strategic recommendations"""
        
        # This will be implemented for weekly reporting
        return []