"""
Competitive Report Generator

Creates strategic intelligence reports and briefings from competitive analysis.
Generates automated daily/weekly reports with actionable insights and recommendations.

Phase 3D: Strategic Intelligence Reporting
"""

import json
import logging
from pathlib import Path
from datetime import datetime, timezone, timedelta
from typing import Dict, List, Optional, Any
from dataclasses import asdict
from jinja2 import Environment, FileSystemLoader, Template

from .models.competitive_result import CompetitiveAnalysisResult
from .models.comparative_metrics import ComparativeMetrics, TrendingTopic
from .models.content_gap import ContentGap, ContentOpportunity, GapAnalysisReport
from ..intelligence_aggregator import AnalysisResult


class CompetitiveBriefing:
    """Daily competitive intelligence briefing"""
    
    def __init__(
        self,
        briefing_date: datetime,
        new_competitive_content: List[CompetitiveAnalysisResult],
        trending_topics: List[TrendingTopic],
        urgent_gaps: List[ContentGap],
        key_insights: List[str],
        action_items: List[str]
    ):
        self.briefing_date = briefing_date
        self.new_competitive_content = new_competitive_content
        self.trending_topics = trending_topics
        self.urgent_gaps = urgent_gaps
        self.key_insights = key_insights
        self.action_items = action_items
    
    def to_dict(self) -> Dict[str, Any]:
        return {
            'briefing_date': self.briefing_date.isoformat(),
            'new_competitive_content': [item.to_competitive_dict() for item in self.new_competitive_content],
            'trending_topics': [topic.to_dict() for topic in self.trending_topics],
            'urgent_gaps': [gap.to_dict() for gap in self.urgent_gaps],
            'key_insights': self.key_insights,
            'action_items': self.action_items,
            'summary': {
                'new_content_count': len(self.new_competitive_content),
                'trending_topics_count': len(self.trending_topics),
                'urgent_gaps_count': len(self.urgent_gaps)
            }
        }


class StrategicReport:
    """Weekly strategic competitive analysis report"""
    
    def __init__(
        self,
        report_date: datetime,
        timeframe: str,
        comparative_metrics: ComparativeMetrics,
        gap_analysis: GapAnalysisReport,
        strategic_opportunities: List[ContentOpportunity],
        competitive_movements: List[Dict[str, Any]],
        recommendations: List[str],
        next_week_priorities: List[str]
    ):
        self.report_date = report_date
        self.timeframe = timeframe
        self.comparative_metrics = comparative_metrics
        self.gap_analysis = gap_analysis
        self.strategic_opportunities = strategic_opportunities
        self.competitive_movements = competitive_movements
        self.recommendations = recommendations
        self.next_week_priorities = next_week_priorities
    
    def to_dict(self) -> Dict[str, Any]:
        return {
            'report_date': self.report_date.isoformat(),
            'timeframe': self.timeframe,
            'comparative_metrics': self.comparative_metrics.to_dict(),
            'gap_analysis': self.gap_analysis.to_dict(),
            'strategic_opportunities': [opp.to_dict() for opp in self.strategic_opportunities],
            'competitive_movements': self.competitive_movements,
            'recommendations': self.recommendations,
            'next_week_priorities': self.next_week_priorities,
            'executive_summary': self._generate_executive_summary()
        }
    
    def _generate_executive_summary(self) -> Dict[str, Any]:
        """Generate executive summary for the report"""
        return {
            'market_position': f"HKIA ranks #{self._calculate_market_position()} in competitive landscape",
            'key_opportunities': len([opp for opp in self.strategic_opportunities if opp.revenue_impact_potential == "high"]),
            'urgent_actions': len([rec for rec in self.recommendations if "urgent" in rec.lower()]),
            'engagement_performance': self._summarize_engagement_performance(),
            'content_gaps': len(self.gap_analysis.identified_gaps),
            'trending_topics': len(self.comparative_metrics.trending_topics)
        }
    
    def _calculate_market_position(self) -> int:
        """Calculate HKIA's market position ranking"""
        # Simplified calculation based on engagement comparison
        leaders = self.comparative_metrics.engagement_comparison.engagement_leaders
        if 'hkia' in leaders:
            return leaders.index('hkia') + 1
        else:
            return len(leaders) + 1
    
    def _summarize_engagement_performance(self) -> str:
        """Summarize engagement performance vs competitors"""
        hkia_engagement = self.comparative_metrics.engagement_comparison.hkia_avg_engagement
        if hkia_engagement > 0.03:
            return "strong"
        elif hkia_engagement > 0.015:
            return "moderate"
        else:
            return "needs_improvement"


class TrendAlert:
    """Alert for significant competitive movements"""
    
    def __init__(
        self,
        alert_date: datetime,
        alert_type: str,
        competitor: str,
        trend_description: str,
        impact_assessment: str,
        recommended_response: str,
        urgency_level: str
    ):
        self.alert_date = alert_date
        self.alert_type = alert_type
        self.competitor = competitor
        self.trend_description = trend_description
        self.impact_assessment = impact_assessment
        self.recommended_response = recommended_response
        self.urgency_level = urgency_level
    
    def to_dict(self) -> Dict[str, Any]:
        return {
            'alert_date': self.alert_date.isoformat(),
            'alert_type': self.alert_type,
            'competitor': self.competitor,
            'trend_description': self.trend_description,
            'impact_assessment': self.impact_assessment,
            'recommended_response': self.recommended_response,
            'urgency_level': self.urgency_level
        }


class StrategyRecommendations:
    """AI-generated strategic recommendations"""
    
    def __init__(
        self,
        recommendations_date: datetime,
        content_strategy_recommendations: List[str],
        competitive_positioning_advice: List[str],
        tactical_actions: List[str],
        resource_allocation_suggestions: List[str],
        performance_targets: Dict[str, float]
    ):
        self.recommendations_date = recommendations_date
        self.content_strategy_recommendations = content_strategy_recommendations
        self.competitive_positioning_advice = competitive_positioning_advice
        self.tactical_actions = tactical_actions
        self.resource_allocation_suggestions = resource_allocation_suggestions
        self.performance_targets = performance_targets
    
    def to_dict(self) -> Dict[str, Any]:
        return {
            'recommendations_date': self.recommendations_date.isoformat(),
            'content_strategy_recommendations': self.content_strategy_recommendations,
            'competitive_positioning_advice': self.competitive_positioning_advice,
            'tactical_actions': self.tactical_actions,
            'resource_allocation_suggestions': self.resource_allocation_suggestions,
            'performance_targets': self.performance_targets
        }


class CompetitiveReportGenerator:
    """
    Creates competitive intelligence reports and strategic briefings.
    
    Generates automated daily briefings, weekly strategic reports, trend alerts,
    and AI-powered strategic recommendations for content strategy.
    """
    
    def __init__(self, data_dir: Path, logs_dir: Path):
        """
        Initialize competitive report generator.
        
        Args:
            data_dir: Base data directory
            logs_dir: Logging directory
        """
        self.data_dir = data_dir
        self.logs_dir = logs_dir
        self.logger = logging.getLogger(f"{__name__}.CompetitiveReportGenerator")
        
        # Report output directories
        self.reports_dir = data_dir / "competitive_intelligence" / "reports"
        self.reports_dir.mkdir(parents=True, exist_ok=True)
        
        self.briefings_dir = self.reports_dir / "daily_briefings"
        self.briefings_dir.mkdir(parents=True, exist_ok=True)
        
        self.strategic_dir = self.reports_dir / "strategic_reports"
        self.strategic_dir.mkdir(parents=True, exist_ok=True)
        
        self.alerts_dir = self.reports_dir / "trend_alerts"
        self.alerts_dir.mkdir(parents=True, exist_ok=True)
        
        # Template system for report formatting
        self._setup_templates()
        
        # Report generation configuration
        self.min_trend_threshold = 0.3
        self.alert_thresholds = {
            'engagement_spike': 2.0,  # 2x increase
            'content_volume_spike': 1.5,  # 1.5x increase
            'new_competitor_detection': True
        }
        
        self.logger.info("Initialized competitive report generator")
    
    def _setup_templates(self):
        """Setup Jinja2 templates for report formatting"""
        # For now, use simple string templates
        # Could be extended with proper Jinja2 templates from files
        self.templates = {
            'daily_briefing': self._get_daily_briefing_template(),
            'strategic_report': self._get_strategic_report_template(),
            'trend_alert': self._get_trend_alert_template()
        }
    
    async def generate_daily_briefing(
        self,
        new_competitive_content: List[CompetitiveAnalysisResult],
        comparative_metrics: Optional[ComparativeMetrics] = None,
        identified_gaps: Optional[List[ContentGap]] = None
    ) -> CompetitiveBriefing:
        """
        Generate daily competitive intelligence briefing.
        
        Args:
            new_competitive_content: New competitive content from last 24h
            comparative_metrics: Optional comparative metrics
            identified_gaps: Optional content gaps identified
            
        Returns:
            Daily competitive briefing
        """
        self.logger.info(f"Generating daily briefing with {len(new_competitive_content)} new items")
        
        briefing_date = datetime.now(timezone.utc)
        
        # Extract trending topics from comparative metrics
        trending_topics = []
        if comparative_metrics:
            trending_topics = comparative_metrics.trending_topics[:5]  # Top 5 trends
        
        # Identify urgent gaps
        urgent_gaps = []
        if identified_gaps:
            urgent_gaps = [gap for gap in identified_gaps 
                          if gap.priority.value in ['critical', 'high']][:3]  # Top 3 urgent
        
        # Generate key insights
        key_insights = self._generate_daily_insights(
            new_competitive_content, comparative_metrics, urgent_gaps
        )
        
        # Generate action items
        action_items = self._generate_daily_action_items(
            new_competitive_content, trending_topics, urgent_gaps
        )
        
        briefing = CompetitiveBriefing(
            briefing_date=briefing_date,
            new_competitive_content=new_competitive_content,
            trending_topics=trending_topics,
            urgent_gaps=urgent_gaps,
            key_insights=key_insights,
            action_items=action_items
        )
        
        # Save briefing
        await self._save_daily_briefing(briefing)
        
        self.logger.info(f"Generated daily briefing with {len(key_insights)} insights and {len(action_items)} actions")
        
        return briefing
    
    async def generate_weekly_strategic_report(
        self,
        comparative_metrics: ComparativeMetrics,
        gap_analysis: GapAnalysisReport,
        strategic_opportunities: List[ContentOpportunity],
        week_competitive_content: List[CompetitiveAnalysisResult]
    ) -> StrategicReport:
        """
        Generate weekly strategic competitive analysis report.
        
        Args:
            comparative_metrics: Weekly comparative metrics
            gap_analysis: Content gap analysis results
            strategic_opportunities: Strategic opportunities identified
            week_competitive_content: Week's competitive content
            
        Returns:
            Strategic report
        """
        self.logger.info("Generating weekly strategic report")
        
        report_date = datetime.now(timezone.utc)
        timeframe = "last_7_days"
        
        # Analyze competitive movements
        competitive_movements = self._analyze_competitive_movements(week_competitive_content)
        
        # Generate strategic recommendations
        recommendations = self._generate_strategic_recommendations(
            comparative_metrics, gap_analysis, strategic_opportunities
        )
        
        # Set next week priorities
        next_week_priorities = self._set_next_week_priorities(
            strategic_opportunities, gap_analysis.priority_actions
        )
        
        report = StrategicReport(
            report_date=report_date,
            timeframe=timeframe,
            comparative_metrics=comparative_metrics,
            gap_analysis=gap_analysis,
            strategic_opportunities=strategic_opportunities,
            competitive_movements=competitive_movements,
            recommendations=recommendations,
            next_week_priorities=next_week_priorities
        )
        
        # Save report
        await self._save_strategic_report(report)
        
        self.logger.info(f"Generated strategic report with {len(recommendations)} recommendations")
        
        return report
    
    async def create_trend_alert(
        self, 
        competitive_content: List[CompetitiveAnalysisResult],
        trend_threshold: Optional[float] = None
    ) -> Optional[TrendAlert]:
        """
        Create trend alert for significant competitive movements.
        
        Args:
            competitive_content: Recent competitive content
            trend_threshold: Optional custom threshold
            
        Returns:
            Trend alert if significant movement detected
        """
        threshold = trend_threshold or self.min_trend_threshold
        
        # Analyze for significant trends
        significant_trends = self._detect_significant_trends(competitive_content, threshold)
        
        if significant_trends:
            # Create alert for most significant trend
            top_trend = max(significant_trends, key=lambda t: t['impact_score'])
            
            alert = TrendAlert(
                alert_date=datetime.now(timezone.utc),
                alert_type=top_trend['type'],
                competitor=top_trend['competitor'],
                trend_description=top_trend['description'],
                impact_assessment=top_trend['impact_assessment'],
                recommended_response=top_trend['recommended_response'],
                urgency_level=top_trend['urgency_level']
            )
            
            # Save alert
            await self._save_trend_alert(alert)
            
            self.logger.warning(f"Generated {alert.urgency_level} trend alert: {alert.trend_description}")
            
            return alert
        
        return None
    
    async def generate_content_strategy_recommendations(
        self,
        comparative_metrics: ComparativeMetrics,
        content_gaps: List[ContentGap],
        strategic_opportunities: List[ContentOpportunity]
    ) -> StrategyRecommendations:
        """
        Generate AI-powered strategic recommendations.
        
        Args:
            comparative_metrics: Comparative performance metrics
            content_gaps: Identified content gaps
            strategic_opportunities: Strategic opportunities
            
        Returns:
            Strategic recommendations
        """
        self.logger.info("Generating AI-powered strategic recommendations")
        
        # Content strategy recommendations
        content_strategy_recommendations = self._generate_content_strategy_advice(
            comparative_metrics, content_gaps
        )
        
        # Competitive positioning advice
        competitive_positioning_advice = self._generate_positioning_advice(
            comparative_metrics, strategic_opportunities
        )
        
        # Tactical actions
        tactical_actions = self._generate_tactical_actions(content_gaps, strategic_opportunities)
        
        # Resource allocation suggestions
        resource_allocation_suggestions = self._generate_resource_allocation_advice(
            strategic_opportunities
        )
        
        # Performance targets
        performance_targets = self._set_performance_targets(comparative_metrics)
        
        recommendations = StrategyRecommendations(
            recommendations_date=datetime.now(timezone.utc),
            content_strategy_recommendations=content_strategy_recommendations,
            competitive_positioning_advice=competitive_positioning_advice,
            tactical_actions=tactical_actions,
            resource_allocation_suggestions=resource_allocation_suggestions,
            performance_targets=performance_targets
        )
        
        # Save recommendations
        await self._save_strategy_recommendations(recommendations)
        
        self.logger.info(f"Generated strategic recommendations with {len(content_strategy_recommendations)} content strategies")
        
        return recommendations
    
    # Helper methods for insight generation
    
    def _generate_daily_insights(
        self,
        new_content: List[CompetitiveAnalysisResult],
        comparative_metrics: Optional[ComparativeMetrics],
        urgent_gaps: List[ContentGap]
    ) -> List[str]:
        """Generate daily insights from competitive analysis"""
        insights = []
        
        if new_content:
            # New content insights
            avg_engagement = sum(
                float(item.engagement_metrics.get('engagement_rate', 0))
                for item in new_content if item.engagement_metrics
            ) / len(new_content)
            
            insights.append(f"New competitive content average engagement: {avg_engagement:.1%}")
            
            # Top performer
            top_performer = max(
                new_content,
                key=lambda x: float(x.engagement_metrics.get('engagement_rate', 0)) if x.engagement_metrics else 0
            )
            if top_performer.engagement_metrics:
                insights.append(f"Top performing content: {top_performer.title} by {top_performer.competitor_name} ({float(top_performer.engagement_metrics.get('engagement_rate', 0)):.1%} engagement)")
        
        if comparative_metrics and comparative_metrics.trending_topics:
            trending_topic = comparative_metrics.trending_topics[0]
            insights.append(f"Trending topic: {trending_topic.topic} (led by {trending_topic.leading_competitor})")
        
        if urgent_gaps:
            insights.append(f"Urgent content gaps identified: {len(urgent_gaps)} critical/high priority areas")
        
        return insights
    
    def _generate_daily_action_items(
        self,
        new_content: List[CompetitiveAnalysisResult],
        trending_topics: List[TrendingTopic],
        urgent_gaps: List[ContentGap]
    ) -> List[str]:
        """Generate daily action items"""
        actions = []
        
        if urgent_gaps:
            actions.append(f"Review and prioritize {len(urgent_gaps)} urgent content gaps")
            if urgent_gaps[0].recommended_action:
                actions.append(f"Consider implementing: {urgent_gaps[0].recommended_action}")
        
        if trending_topics:
            actions.append(f"Evaluate content opportunities in trending topic: {trending_topics[0].topic}")
        
        if new_content:
            high_performers = [
                item for item in new_content
                if item.engagement_metrics and float(item.engagement_metrics.get('engagement_rate', 0)) > 0.05
            ]
            if high_performers:
                actions.append(f"Analyze {len(high_performers)} high-performing competitive posts for strategy insights")
        
        return actions
    
    # Report saving methods
    
    async def _save_daily_briefing(self, briefing: CompetitiveBriefing):
        """Save daily briefing to file"""
        timestamp = briefing.briefing_date.strftime("%Y%m%d")
        
        # Save JSON data
        json_file = self.briefings_dir / f"daily_briefing_{timestamp}.json"
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(briefing.to_dict(), f, indent=2, ensure_ascii=False)
        
        # Save formatted text report
        text_file = self.briefings_dir / f"daily_briefing_{timestamp}.md"
        formatted_report = self._format_daily_briefing(briefing)
        with open(text_file, 'w', encoding='utf-8') as f:
            f.write(formatted_report)
        
        self.logger.info(f"Saved daily briefing to {json_file}")
    
    async def _save_strategic_report(self, report: StrategicReport):
        """Save strategic report to file"""
        timestamp = report.report_date.strftime("%Y%m%d")
        
        # Save JSON data
        json_file = self.strategic_dir / f"strategic_report_{timestamp}.json"
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(report.to_dict(), f, indent=2, ensure_ascii=False)
        
        # Save formatted text report
        text_file = self.strategic_dir / f"strategic_report_{timestamp}.md"
        formatted_report = self._format_strategic_report(report)
        with open(text_file, 'w', encoding='utf-8') as f:
            f.write(formatted_report)
        
        self.logger.info(f"Saved strategic report to {json_file}")
    
    async def _save_trend_alert(self, alert: TrendAlert):
        """Save trend alert to file"""
        timestamp = alert.alert_date.strftime("%Y%m%d_%H%M%S")
        
        # Save JSON data
        json_file = self.alerts_dir / f"trend_alert_{timestamp}.json"
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(alert.to_dict(), f, indent=2, ensure_ascii=False)
        
        self.logger.info(f"Saved trend alert to {json_file}")
    
    async def _save_strategy_recommendations(self, recommendations: StrategyRecommendations):
        """Save strategy recommendations to file"""
        timestamp = recommendations.recommendations_date.strftime("%Y%m%d")
        
        # Save JSON data
        json_file = self.strategic_dir / f"strategy_recommendations_{timestamp}.json"
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(recommendations.to_dict(), f, indent=2, ensure_ascii=False)
        
        self.logger.info(f"Saved strategy recommendations to {json_file}")
    
    # Report formatting methods
    
    def _format_daily_briefing(self, briefing: CompetitiveBriefing) -> str:
        """Format daily briefing as markdown"""
        report = f"""# Daily Competitive Intelligence Briefing

**Date**: {briefing.briefing_date.strftime('%Y-%m-%d')}

## Executive Summary

- **New Competitive Content**: {len(briefing.new_competitive_content)} items
- **Trending Topics**: {len(briefing.trending_topics)} identified
- **Urgent Gaps**: {len(briefing.urgent_gaps)} requiring attention

## Key Insights

"""
        for insight in briefing.key_insights:
            report += f"- {insight}\n"
        
        report += "\n## Action Items\n\n"
        for i, action in enumerate(briefing.action_items, 1):
            report += f"{i}. {action}\n"
        
        if briefing.trending_topics:
            report += "\n## Trending Topics\n\n"
            for topic in briefing.trending_topics:
                report += f"- **{topic.topic}** (Score: {topic.trend_score:.2f}) - Led by {topic.leading_competitor}\n"
        
        return report
    
    def _format_strategic_report(self, report: StrategicReport) -> str:
        """Format strategic report as markdown"""
        formatted = f"""# Weekly Strategic Competitive Intelligence Report

**Date**: {report.report_date.strftime('%Y-%m-%d')}
**Timeframe**: {report.timeframe}

## Executive Summary

{report.to_dict()['executive_summary']}

## Strategic Recommendations

"""
        for i, rec in enumerate(report.recommendations, 1):
            formatted += f"{i}. {rec}\n"
        
        formatted += "\n## Next Week Priorities\n\n"
        for i, priority in enumerate(report.next_week_priorities, 1):
            formatted += f"{i}. {priority}\n"
        
        return formatted
    
    # Template methods (simplified - could be moved to external template files)
    
    def _get_daily_briefing_template(self) -> str:
        return """# Daily Competitive Intelligence Briefing
{{ briefing_date }}
{{ summary }}
{{ insights }}
{{ actions }}
"""
    
    def _get_strategic_report_template(self) -> str:
        return """# Strategic Competitive Intelligence Report
{{ report_date }}
{{ executive_summary }}
{{ recommendations }}
{{ priorities }}
"""
    
    def _get_trend_alert_template(self) -> str:
        return """# TREND ALERT: {{ urgency_level }}
{{ trend_description }}
{{ impact_assessment }}
{{ recommended_response }}
"""
    
    # Additional helper methods would be implemented here...
    # (Implementation continues with remaining functionality)