"""
Executive Reporting Engine

C-Suite and Board-level reporting for strategic decision making.
Designed for CMO, CFO, and Board presentations.
"""

from typing import Dict, Any, Optional
from datetime import datetime, timedelta

from .base.engine import BaseEngine
from .errors import EngineError as MetaAPIError
from .logging import get_logger

logger = get_logger(__name__)


class ExecutiveReportingEngine(BaseEngine):
    """Executive-level reporting and analysis engine.
    
    Capabilities:
    - CEO dashboard (top 5 metrics)
    - Board presentation generation
    - CFO financial reporting
    - Strategic insights
    """
    
    async def initialize(self) -> None:
        """Initialize executive reporting engine."""
        logger.info("executive_reporting_engine_initialized")
        self._initialized = True
    
    async def shutdown(self) -> None:
        """Shutdown executive reporting engine."""
        logger.info("executive_reporting_engine_shutdown")
        self._shutdown = True
    
    async def generate_ceo_dashboard(
        self,
        ad_account_id: str,
        time_range: Optional[Dict[str, str]] = None,
        comparison_period: str = "previous_period"
    ) -> Dict[str, Any]:
        """Generate CEO dashboard with top 5 strategic metrics.
        
        Metrics:
        1. ROAS (Return on Ad Spend)
        2. CAC (Customer Acquisition Cost)
        3. Market Share / Share of Voice
        4. Efficiency Trend
        5. Budget Utilization
        
        Args:
            ad_account_id: Meta ad account ID
            time_range: Analysis period
            comparison_period: 'previous_period', 'last_year', or 'last_quarter'
        
        Returns:
            Executive dashboard with key metrics and trends
        """
        await self._ensure_initialized()
        
        if not time_range:
            # Default to last 30 days
            time_range = {
                "since": (datetime.now() - timedelta(days=30)).strftime("%Y-%m-%d"),
                "until": datetime.now().strftime("%Y-%m-%d")
            }
        
        logger.info("generating_ceo_dashboard", ad_account_id=ad_account_id)
        
        try:
            # Get current period insights
            insights = await self.client.get_insights(
                object_id=ad_account_id,
                level="account",
                fields=[
                    "spend",
                    "impressions",
                    "clicks",
                    "actions",
                    "action_values",
                    "ctr",
                    "cpc",
                    "cpm",
                    "cost_per_action_type"
                ],
                time_range=time_range,
                action_breakdowns=["action_type"]
            )
            
            data = insights.get("data", [])
            if not data:
                return {
                    "error": "No data available for the specified period",
                    "ad_account_id": ad_account_id,
                    "time_range": time_range
                }
            
            # Calculate current period metrics
            total_spend = sum(float(d.get("spend", 0)) for d in data)
            total_impressions = sum(int(d.get("impressions", 0)) for d in data)
            total_clicks = sum(int(d.get("clicks", 0)) for d in data)
            
            # Calculate revenue from conversions
            total_revenue = 0
            total_conversions = 0
            for insight in data:
                actions = insight.get("actions", [])
                action_values = insight.get("action_values", [])
                
                for action in actions:
                    if action.get("action_type") in ["purchase", "omni_purchase"]:
                        total_conversions += int(action.get("value", 0))
                
                for action_value in action_values:
                    if action_value.get("action_type") in ["purchase", "omni_purchase"]:
                        total_revenue += float(action_value.get("value", 0))
            
            # Calculate key metrics
            roas = (total_revenue / total_spend) if total_spend > 0 else 0
            cac = (total_spend / total_conversions) if total_conversions > 0 else 0
            ctr = (total_clicks / total_impressions * 100) if total_impressions > 0 else 0
            
            # Get comparison period data
            comparison_metrics = await self._get_comparison_period(
                ad_account_id, time_range, comparison_period
            )
            
            dashboard = {
                "report_type": "CEO Dashboard",
                "ad_account_id": ad_account_id,
                "time_range": time_range,
                "generated_at": datetime.now().isoformat(),
                "key_metrics": {
                    "1_roas": {
                        "label": "Return on Ad Spend",
                        "current": round(roas, 2),
                        "previous": round(comparison_metrics.get("roas", 0), 2),
                        "change_percentage": self._calculate_change(roas, comparison_metrics.get("roas", 0)),
                        "trend": "up" if roas > comparison_metrics.get("roas", 0) else "down",
                        "status": "excellent" if roas > 4 else "good" if roas > 2 else "fair" if roas > 1 else "poor",
                        "target": 3.0,
                        "unit": "x"
                    },
                    "2_cac": {
                        "label": "Customer Acquisition Cost",
                        "current": round(cac, 2),
                        "previous": round(comparison_metrics.get("cac", 0), 2),
                        "change_percentage": self._calculate_change(cac, comparison_metrics.get("cac", 0)),
                        "trend": "down" if cac < comparison_metrics.get("cac", 0) else "up",
                        "status": "excellent" if cac < 50 else "good" if cac < 100 else "fair" if cac < 150 else "poor",
                        "target": 75.0,
                        "unit": "$"
                    },
                    "3_efficiency": {
                        "label": "Campaign Efficiency (CTR)",
                        "current": round(ctr, 2),
                        "previous": round(comparison_metrics.get("ctr", 0), 2),
                        "change_percentage": self._calculate_change(ctr, comparison_metrics.get("ctr", 0)),
                        "trend": "up" if ctr > comparison_metrics.get("ctr", 0) else "down",
                        "status": "excellent" if ctr > 2 else "good" if ctr > 1 else "fair" if ctr > 0.5 else "poor",
                        "target": 1.5,
                        "unit": "%"
                    },
                    "4_scale": {
                        "label": "Marketing Investment",
                        "current": round(total_spend, 2),
                        "previous": round(comparison_metrics.get("spend", 0), 2),
                        "change_percentage": self._calculate_change(total_spend, comparison_metrics.get("spend", 0)),
                        "trend": "up" if total_spend > comparison_metrics.get("spend", 0) else "down",
                        "status": "info",
                        "unit": "$"
                    },
                    "5_revenue": {
                        "label": "Revenue Generated",
                        "current": round(total_revenue, 2),
                        "previous": round(comparison_metrics.get("revenue", 0), 2),
                        "change_percentage": self._calculate_change(total_revenue, comparison_metrics.get("revenue", 0)),
                        "trend": "up" if total_revenue > comparison_metrics.get("revenue", 0) else "down",
                        "status": "excellent" if total_revenue > total_spend * 3 else "good" if total_revenue > total_spend * 2 else "fair",
                        "unit": "$"
                    }
                },
                "summary": {
                    "total_spend": round(total_spend, 2),
                    "total_revenue": round(total_revenue, 2),
                    "total_conversions": total_conversions,
                    "profit": round(total_revenue - total_spend, 2),
                    "profit_margin": round(((total_revenue - total_spend) / total_revenue * 100), 2) if total_revenue > 0 else 0
                },
                "executive_insights": []
            }
            
            # Generate executive insights
            if roas > 4:
                dashboard["executive_insights"].append({
                    "type": "success",
                    "message": f"Exceptional ROAS of {roas:.1f}x - Strong ROI performance",
                    "recommendation": "Consider scaling investment to capitalize on high returns"
                })
            elif roas < 1:
                dashboard["executive_insights"].append({
                    "type": "warning",
                    "message": f"ROAS below break-even at {roas:.1f}x",
                    "recommendation": "Immediate optimization required or consider pausing unprofitable campaigns"
                })
            
            if cac < 50 and total_conversions > 100:
                dashboard["executive_insights"].append({
                    "type": "success",
                    "message": f"Highly efficient customer acquisition at ${cac:.2f}/customer",
                    "recommendation": "Excellent opportunity to scale aggressively"
                })
            
            # Trend analysis
            if dashboard["key_metrics"]["1_roas"]["change_percentage"] > 20:
                dashboard["executive_insights"].append({
                    "type": "success",
                    "message": f"ROAS improved by {dashboard['key_metrics']['1_roas']['change_percentage']:.0f}%",
                    "recommendation": "Continue current optimization strategies"
                })
            elif dashboard["key_metrics"]["1_roas"]["change_percentage"] < -20:
                dashboard["executive_insights"].append({
                    "type": "warning",
                    "message": f"ROAS declined by {abs(dashboard['key_metrics']['1_roas']['change_percentage']):.0f}%",
                    "recommendation": "Investigate performance decline and adjust strategy"
                })
            
            logger.info("ceo_dashboard_generated", roas=roas, cac=cac)
            return dashboard
            
        except Exception as e:
            logger.error("ceo_dashboard_generation_failed", error=str(e))
            raise MetaAPIError(f"CEO dashboard generation failed: {str(e)}")
    
    def _calculate_change(self, current: float, previous: float) -> float:
        """Calculate percentage change between periods."""
        if previous == 0:
            return 0 if current == 0 else 100
        return round(((current - previous) / previous * 100), 2)
    
    async def _get_comparison_period(
        self,
        ad_account_id: str,
        current_time_range: Dict[str, str],
        comparison_period: str
    ) -> Dict[str, float]:
        """Get metrics for comparison period."""
        # Calculate comparison period dates
        since_date = datetime.strptime(current_time_range["since"], "%Y-%m-%d")
        until_date = datetime.strptime(current_time_range["until"], "%Y-%m-%d")
        period_length = (until_date - since_date).days
        
        if comparison_period == "previous_period":
            comp_until = since_date - timedelta(days=1)
            comp_since = comp_until - timedelta(days=period_length)
        elif comparison_period == "last_year":
            comp_since = since_date - timedelta(days=365)
            comp_until = until_date - timedelta(days=365)
        else:  # last_quarter
            comp_since = since_date - timedelta(days=90)
            comp_until = until_date - timedelta(days=90)
        
        comp_time_range = {
            "since": comp_since.strftime("%Y-%m-%d"),
            "until": comp_until.strftime("%Y-%m-%d")
        }
        
        try:
            # Get comparison period data
            insights = await self.client.get_insights(
                object_id=ad_account_id,
                level="account",
                fields=["spend", "impressions", "clicks", "actions", "action_values"],
                time_range=comp_time_range,
                action_breakdowns=["action_type"]
            )
            
            data = insights.get("data", [])
            
            # Calculate metrics
            spend = sum(float(d.get("spend", 0)) for d in data)
            impressions = sum(int(d.get("impressions", 0)) for d in data)
            clicks = sum(int(d.get("clicks", 0)) for d in data)
            
            revenue = 0
            conversions = 0
            for insight in data:
                actions = insight.get("actions", [])
                action_values = insight.get("action_values", [])
                
                for action in actions:
                    if action.get("action_type") in ["purchase", "omni_purchase"]:
                        conversions += int(action.get("value", 0))
                
                for action_value in action_values:
                    if action_value.get("action_type") in ["purchase", "omni_purchase"]:
                        revenue += float(action_value.get("value", 0))
            
            return {
                "spend": spend,
                "revenue": revenue,
                "conversions": conversions,
                "roas": (revenue / spend) if spend > 0 else 0,
                "cac": (spend / conversions) if conversions > 0 else 0,
                "ctr": (clicks / impressions * 100) if impressions > 0 else 0
            }
            
        except Exception:
            return {
                "spend": 0,
                "revenue": 0,
                "conversions": 0,
                "roas": 0,
                "cac": 0,
                "ctr": 0
            }
    
    async def generate_board_presentation(
        self,
        ad_account_id: str,
        time_range: Optional[Dict[str, str]] = None,
        include_competitive: bool = True
    ) -> Dict[str, Any]:
        """Generate board-ready presentation materials.
        
        Includes:
        - Executive summary
        - Key performance indicators
        - Competitive positioning
        - Strategic recommendations
        - Investment justification
        
        Args:
            ad_account_id: Meta ad account ID
            time_range: Analysis period
            include_competitive: Include competitive analysis
        
        Returns:
            Board presentation deck data
        """
        await self._ensure_initialized()
        
        if not time_range:
            # Default to quarterly view
            time_range = {
                "since": (datetime.now() - timedelta(days=90)).strftime("%Y-%m-%d"),
                "until": datetime.now().strftime("%Y-%m-%d")
            }
        
        logger.info("generating_board_presentation", ad_account_id=ad_account_id)
        
        try:
            # Get CEO dashboard as foundation
            ceo_dashboard = await self.generate_ceo_dashboard(
                ad_account_id, time_range, "previous_period"
            )
            
            presentation = {
                "title": "Meta Advertising Performance Review",
                "subtitle": "Board of Directors Presentation",
                "period": time_range,
                "generated_at": datetime.now().isoformat(),
                "slides": []
            }
            
            # Slide 1: Executive Summary
            presentation["slides"].append({
                "slide_number": 1,
                "title": "Executive Summary",
                "content": {
                    "headline_metrics": ceo_dashboard["key_metrics"],
                    "summary_statement": self._generate_summary_statement(ceo_dashboard),
                    "period_performance": "Quarter" if (datetime.strptime(time_range["until"], "%Y-%m-%d") - 
                                                       datetime.strptime(time_range["since"], "%Y-%m-%d")).days > 60 else "Period"
                }
            })
            
            # Slide 2: Financial Performance
            presentation["slides"].append({
                "slide_number": 2,
                "title": "Financial Performance",
                "content": {
                    "investment": ceo_dashboard["summary"]["total_spend"],
                    "revenue": ceo_dashboard["summary"]["total_revenue"],
                    "profit": ceo_dashboard["summary"]["profit"],
                    "roi": ceo_dashboard["key_metrics"]["1_roas"]["current"],
                    "profit_margin": ceo_dashboard["summary"]["profit_margin"],
                    "chart_type": "revenue_vs_spend_bar_chart",
                    "chart_data": {
                        "investment": ceo_dashboard["summary"]["total_spend"],
                        "revenue": ceo_dashboard["summary"]["total_revenue"],
                        "profit": ceo_dashboard["summary"]["profit"]
                    }
                }
            })
            
            # Slide 3: Key Performance Indicators
            presentation["slides"].append({
                "slide_number": 3,
                "title": "Key Performance Indicators",
                "content": {
                    "metrics": [
                        {
                            "name": "Return on Ad Spend (ROAS)",
                            "value": f"{ceo_dashboard['key_metrics']['1_roas']['current']}x",
                            "trend": ceo_dashboard["key_metrics"]["1_roas"]["trend"],
                            "status": ceo_dashboard["key_metrics"]["1_roas"]["status"]
                        },
                        {
                            "name": "Customer Acquisition Cost (CAC)",
                            "value": f"${ceo_dashboard['key_metrics']['2_cac']['current']}",
                            "trend": "up" if ceo_dashboard["key_metrics"]["2_cac"]["trend"] == "down" else "down",
                            "status": ceo_dashboard["key_metrics"]["2_cac"]["status"]
                        },
                        {
                            "name": "Campaign Efficiency (CTR)",
                            "value": f"{ceo_dashboard['key_metrics']['3_efficiency']['current']}%",
                            "trend": ceo_dashboard["key_metrics"]["3_efficiency"]["trend"],
                            "status": ceo_dashboard["key_metrics"]["3_efficiency"]["status"]
                        }
                    ]
                }
            })
            
            # Slide 4: Strategic Insights
            presentation["slides"].append({
                "slide_number": 4,
                "title": "Strategic Insights & Recommendations",
                "content": {
                    "insights": ceo_dashboard["executive_insights"],
                    "strategic_priorities": [
                        "Optimize high-performing campaigns for scale",
                        "Test new creative strategies to maintain engagement",
                        "Expand audience reach while maintaining efficiency"
                    ]
                }
            })
            
            # Slide 5: Investment Justification
            presentation["slides"].append({
                "slide_number": 5,
                "title": "Investment Justification",
                "content": {
                    "roi_proof": f"{ceo_dashboard['key_metrics']['1_roas']['current']}x return on every dollar invested",
                    "incremental_revenue": ceo_dashboard["summary"]["total_revenue"],
                    "profit_generated": ceo_dashboard["summary"]["profit"],
                    "recommendation": self._generate_investment_recommendation(ceo_dashboard),
                    "risk_assessment": "Low" if ceo_dashboard["key_metrics"]["1_roas"]["current"] > 2 else "Medium"
                }
            })
            
            presentation["presentation_notes"] = {
                "format": "Ready for PowerPoint/Keynote export",
                "charts_needed": ["revenue_vs_spend", "roas_trend", "kpi_scorecards"],
                "talking_points": [
                    f"Generated ${ceo_dashboard['summary']['total_revenue']:,.2f} in revenue from ${ceo_dashboard['summary']['total_spend']:,.2f} investment",
                    f"Achieved {ceo_dashboard['key_metrics']['1_roas']['current']}x ROAS, {'exceeding' if ceo_dashboard['key_metrics']['1_roas']['current'] > 3 else 'meeting'} industry benchmarks",
                    f"Customer acquisition cost of ${ceo_dashboard['key_metrics']['2_cac']['current']:.2f} demonstrates efficient growth"
                ]
            }
            
            logger.info("board_presentation_generated", slides=len(presentation["slides"]))
            return presentation
            
        except Exception as e:
            logger.error("board_presentation_generation_failed", error=str(e))
            raise MetaAPIError(f"Board presentation generation failed: {str(e)}")
    
    def _generate_summary_statement(self, dashboard: Dict[str, Any]) -> str:
        """Generate executive summary statement."""
        roas = dashboard["key_metrics"]["1_roas"]["current"]
        revenue = dashboard["summary"]["total_revenue"]
        spend = dashboard["summary"]["total_spend"]
        
        if roas > 4:
            return f"Exceptional performance with ${revenue:,.0f} revenue generated from ${spend:,.0f} investment, achieving {roas:.1f}x ROAS."
        elif roas > 2:
            return f"Strong performance with ${revenue:,.0f} revenue from ${spend:,.0f} investment, delivering {roas:.1f}x return."
        elif roas > 1:
            return f"Positive performance with ${revenue:,.0f} revenue from ${spend:,.0f} investment, achieving {roas:.1f}x ROAS."
        else:
            return f"Investment of ${spend:,.0f} generated ${revenue:,.0f} in revenue. Optimization recommended to improve {roas:.1f}x ROAS."
    
    def _generate_investment_recommendation(self, dashboard: Dict[str, Any]) -> str:
        """Generate investment recommendation."""
        roas = dashboard["key_metrics"]["1_roas"]["current"]
        
        if roas > 4:
            return "Recommend increasing investment by 50-100% to capitalize on exceptional returns"
        elif roas > 3:
            return "Recommend increasing investment by 25-50% given strong positive ROI"
        elif roas > 2:
            return "Maintain or moderately increase investment (10-25%) while optimizing"
        elif roas > 1:
            return "Maintain current investment level, focus on optimization before scaling"
        else:
            return "Recommend optimization before additional investment, or reduce investment by 25-50%"
    
    async def generate_cfo_financial_report(
        self,
        ad_account_id: str,
        time_range: Optional[Dict[str, str]] = None,
        include_forecast: bool = True
    ) -> Dict[str, Any]:
        """Generate CFO-focused financial report.
        
        Includes:
        - Revenue attribution
        - Cash flow impact
        - Budget utilization
        - Financial forecasting
        - P&L contribution
        
        Args:
            ad_account_id: Meta ad account ID
            time_range: Analysis period
            include_forecast: Include financial forecasts
        
        Returns:
            CFO financial report
        """
        await self._ensure_initialized()
        
        if not time_range:
            # Default to current month
            month_start = datetime.now().replace(day=1).strftime("%Y-%m-%d")
            time_range = {
                "since": month_start,
                "until": datetime.now().strftime("%Y-%m-%d")
            }
        
        logger.info("generating_cfo_financial_report", ad_account_id=ad_account_id)
        
        try:
            # Get insights
            insights = await self.client.get_insights(
                object_id=ad_account_id,
                level="account",
                fields=["spend", "actions", "action_values", "impressions", "clicks"],
                time_range=time_range,
                time_increment=1,
                action_breakdowns=["action_type"]
            )
            
            data = insights.get("data", [])
            
            # Calculate financial metrics
            total_spend = sum(float(d.get("spend", 0)) for d in data)
            total_revenue = 0
            total_conversions = 0
            
            for insight in data:
                action_values = insight.get("action_values", [])
                actions = insight.get("actions", [])
                
                for action_value in action_values:
                    if action_value.get("action_type") in ["purchase", "omni_purchase"]:
                        total_revenue += float(action_value.get("value", 0))
                
                for action in actions:
                    if action.get("action_type") in ["purchase", "omni_purchase"]:
                        total_conversions += int(action.get("value", 0))
            
            report = {
                "report_type": "CFO Financial Report",
                "ad_account_id": ad_account_id,
                "time_range": time_range,
                "generated_at": datetime.now().isoformat(),
                "financial_summary": {
                    "marketing_investment": round(total_spend, 2),
                    "revenue_attributed": round(total_revenue, 2),
                    "gross_profit": round(total_revenue - total_spend, 2),
                    "roi_percentage": round(((total_revenue - total_spend) / total_spend * 100), 2) if total_spend > 0 else 0,
                    "profit_margin": round(((total_revenue - total_spend) / total_revenue * 100), 2) if total_revenue > 0 else 0
                },
                "cash_flow_analysis": {
                    "cash_outflow": round(total_spend, 2),
                    "cash_inflow": round(total_revenue, 2),
                    "net_cash_flow": round(total_revenue - total_spend, 2),
                    "working_capital_impact": round(total_spend * -1, 2),  # Negative = outflow
                    "payback_period_days": round((total_spend / total_revenue * len(data)), 1) if total_revenue > 0 else 0
                },
                "budget_utilization": {
                    "days_in_period": len(data),
                    "average_daily_spend": round(total_spend / len(data), 2) if len(data) > 0 else 0,
                    "spend_consistency": "consistent" if len(set([int(d.get("spend", 0)) for d in data])) < len(data) * 0.5 else "variable"
                },
                "p_and_l_contribution": {
                    "revenue_line": round(total_revenue, 2),
                    "marketing_expense_line": round(total_spend, 2),
                    "contribution_to_gross_profit": round(total_revenue - total_spend, 2),
                    "as_percentage_of_revenue": round((total_spend / total_revenue * 100), 2) if total_revenue > 0 else 0
                }
            }
            
            # Add forecast if requested
            if include_forecast and len(data) > 7:
                avg_daily_spend = total_spend / len(data)
                avg_daily_revenue = total_revenue / len(data)
                
                # Project to end of month
                days_remaining = (datetime.now().replace(day=1) + timedelta(days=32)).replace(day=1) - datetime.now()
                days_remaining = days_remaining.days
                
                report["forecast"] = {
                    "end_of_month_spend": round(total_spend + (avg_daily_spend * days_remaining), 2),
                    "end_of_month_revenue": round(total_revenue + (avg_daily_revenue * days_remaining), 2),
                    "projected_profit": round((total_revenue + (avg_daily_revenue * days_remaining)) - 
                                             (total_spend + (avg_daily_spend * days_remaining)), 2),
                    "confidence_level": "medium",
                    "days_remaining": days_remaining
                }
            
            # CFO insights
            report["cfo_insights"] = []
            
            if report["financial_summary"]["roi_percentage"] > 200:
                report["cfo_insights"].append({
                    "type": "opportunity",
                    "message": f"Strong {report['financial_summary']['roi_percentage']:.0f}% ROI presents scaling opportunity",
                    "recommendation": "Consider increasing marketing budget allocation"
                })
            
            if report["financial_summary"]["profit_margin"] > 50:
                report["cfo_insights"].append({
                    "type": "success",
                    "message": f"Healthy {report['financial_summary']['profit_margin']:.0f}% profit margin",
                    "recommendation": "Marketing investment is highly efficient"
                })
            
            if report["cash_flow_analysis"]["payback_period_days"] < 30:
                report["cfo_insights"].append({
                    "type": "success",
                    "message": f"Fast {report['cash_flow_analysis']['payback_period_days']:.0f}-day payback period",
                    "recommendation": "Low working capital risk"
                })
            
            logger.info("cfo_financial_report_generated", revenue=total_revenue, spend=total_spend)
            return report
            
        except Exception as e:
            logger.error("cfo_financial_report_generation_failed", error=str(e))
            raise MetaAPIError(f"CFO financial report generation failed: {str(e)}")

