"""
Tactical Operations Engine

Real-time campaign intelligence and operational tools for media buyers.
Designed for daily campaign management and optimization.
"""

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

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

logger = get_logger(__name__)


class TacticalOperationsEngine(BaseEngine):
    """Tactical operations engine for media buyers.
    
    Capabilities:
    - Hourly performance tracking
    - Campaign health monitoring
    - Real-time alerts
    - Quick action recommendations
    - Budget pacing
    """
    
    async def initialize(self) -> None:
        """Initialize tactical operations engine."""
        logger.info("tactical_operations_engine_initialized")
        self._initialized = True
    
    async def shutdown(self) -> None:
        """Shutdown tactical operations engine."""
        logger.info("tactical_operations_engine_shutdown")
        self._shutdown = True
    
    async def get_hourly_performance_snapshot(
        self,
        ad_account_id: str,
        entity_id: Optional[str] = None,
        entity_type: str = "account"
    ) -> Dict[str, Any]:
        """Get last hour performance vs. yesterday same hour.
        
        Enables media buyers to detect issues within 60 minutes.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Specific campaign/adset/ad ID (optional)
            entity_type: Type of entity (account, campaign, adset, ad)
        
        Returns:
            Hourly performance snapshot with comparisons
        """
        await self._ensure_initialized()
        
        logger.info("getting_hourly_performance_snapshot", entity_type=entity_type)
        
        try:
            target_id = entity_id if entity_id else ad_account_id
            
            # Get today's hourly data
            today = datetime.now().strftime("%Y-%m-%d")
            insights_today = await self.client.get_insights(
                object_id=target_id,
                level=entity_type,
                fields=["spend", "impressions", "clicks", "actions", "ctr", "cpc"],
                breakdowns=["hourly_stats_aggregated_by_advertiser_time_zone"],
                time_range={"since": today, "until": today}
            )
            
            # Get yesterday's hourly data
            yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
            insights_yesterday = await self.client.get_insights(
                object_id=target_id,
                level=entity_type,
                fields=["spend", "impressions", "clicks", "actions", "ctr", "cpc"],
                breakdowns=["hourly_stats_aggregated_by_advertiser_time_zone"],
                time_range={"since": yesterday, "until": yesterday}
            )
            
            current_hour = datetime.now().hour
            
            # Find current hour data
            today_data = insights_today.get("data", [])
            yesterday_data = insights_yesterday.get("data", [])
            
            current_hour_data = next(
                (d for d in today_data if d.get("hourly_stats_aggregated_by_advertiser_time_zone") == str(current_hour)),
                {}
            )
            
            yesterday_hour_data = next(
                (d for d in yesterday_data if d.get("hourly_stats_aggregated_by_advertiser_time_zone") == str(current_hour)),
                {}
            )
            
            # Calculate metrics
            current_spend = float(current_hour_data.get("spend", 0))
            yesterday_spend = float(yesterday_hour_data.get("spend", 0))
            
            current_impressions = int(current_hour_data.get("impressions", 0))
            yesterday_impressions = int(yesterday_hour_data.get("impressions", 0))
            
            current_clicks = int(current_hour_data.get("clicks", 0))
            yesterday_clicks = int(yesterday_hour_data.get("clicks", 0))
            
            current_ctr = float(current_hour_data.get("ctr", 0))
            yesterday_ctr = float(yesterday_hour_data.get("ctr", 0))
            
            snapshot = {
                "entity_id": target_id,
                "entity_type": entity_type,
                "current_hour": current_hour,
                "timestamp": datetime.now().isoformat(),
                "current_hour_performance": {
                    "spend": round(current_spend, 2),
                    "impressions": current_impressions,
                    "clicks": current_clicks,
                    "ctr": round(current_ctr, 2),
                    "cpc": round(float(current_hour_data.get("cpc", 0)), 2)
                },
                "yesterday_same_hour": {
                    "spend": round(yesterday_spend, 2),
                    "impressions": yesterday_impressions,
                    "clicks": yesterday_clicks,
                    "ctr": round(yesterday_ctr, 2),
                    "cpc": round(float(yesterday_hour_data.get("cpc", 0)), 2)
                },
                "changes": {
                    "spend_change_pct": self._calculate_change_pct(current_spend, yesterday_spend),
                    "impressions_change_pct": self._calculate_change_pct(current_impressions, yesterday_impressions),
                    "clicks_change_pct": self._calculate_change_pct(current_clicks, yesterday_clicks),
                    "ctr_change_pct": self._calculate_change_pct(current_ctr, yesterday_ctr)
                },
                "alerts": []
            }
            
            # Generate alerts
            if abs(snapshot["changes"]["spend_change_pct"]) > 50:
                snapshot["alerts"].append({
                    "severity": "high",
                    "type": "spend_anomaly",
                    "message": f"Spend changed {snapshot['changes']['spend_change_pct']:.0f}% vs. yesterday"
                })
            
            if abs(snapshot["changes"]["ctr_change_pct"]) > 30:
                snapshot["alerts"].append({
                    "severity": "medium",
                    "type": "performance_change",
                    "message": f"CTR changed {snapshot['changes']['ctr_change_pct']:.0f}% vs. yesterday"
                })
            
            # Calculate today vs. yesterday totals
            today_total_spend = sum(float(d.get("spend", 0)) for d in today_data)
            yesterday_total_spend = sum(float(d.get("spend", 0)) for d in yesterday_data)
            
            snapshot["day_comparison"] = {
                "today_spend_so_far": round(today_total_spend, 2),
                "yesterday_same_time": round(yesterday_total_spend, 2),
                "day_change_pct": self._calculate_change_pct(today_total_spend, yesterday_total_spend)
            }
            
            logger.info("hourly_performance_snapshot_generated", current_spend=current_spend)
            return snapshot
            
        except Exception as e:
            logger.error("hourly_performance_snapshot_failed", error=str(e))
            raise MetaAPIError(f"Hourly performance snapshot failed: {str(e)}")
    
    def _calculate_change_pct(self, current: float, previous: float) -> float:
        """Calculate percentage change."""
        if previous == 0:
            return 0 if current == 0 else 100
        return round(((current - previous) / previous * 100), 2)
    
    async def check_campaign_health_instant(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "campaign"
    ) -> Dict[str, Any]:
        """5-second campaign health check with red/yellow/green status.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Campaign/adset/ad ID
            entity_type: Type of entity
        
        Returns:
            Instant health score and prioritized actions
        """
        await self._ensure_initialized()
        
        logger.info("checking_campaign_health_instant", entity_id=entity_id)
        
        try:
            # Get last 7 days performance
            time_range = {
                "since": (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d"),
                "until": datetime.now().strftime("%Y-%m-%d")
            }
            
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=[
                    "spend",
                    "impressions",
                    "clicks",
                    "actions",
                    "ctr",
                    "cpc",
                    "cpm",
                    "frequency",
                    "reach"
                ],
                time_range=time_range
            )
            
            data = insights.get("data", [])
            if not data:
                return {
                    "entity_id": entity_id,
                    "health_status": "unknown",
                    "message": "No data available"
                }
            
            insight = data[0]
            
            # Calculate health score (0-100)
            health_score = 100
            issues = []
            warnings = []
            
            # Check 1: CTR (critical)
            ctr = float(insight.get("ctr", 0))
            if ctr < 0.5:
                health_score -= 30
                issues.append("Very low CTR (<0.5%)")
            elif ctr < 1.0:
                health_score -= 15
                warnings.append("Low CTR (<1.0%)")
            
            # Check 2: Frequency (ad fatigue)
            frequency = float(insight.get("frequency", 0))
            if frequency > 5:
                health_score -= 25
                issues.append(f"High frequency ({frequency:.1f}x) - Ad fatigue risk")
            elif frequency > 3:
                health_score -= 10
                warnings.append(f"Moderate frequency ({frequency:.1f}x)")
            
            # Check 3: CPC (cost efficiency)
            cpc = float(insight.get("cpc", 0))
            if cpc > 5:
                health_score -= 20
                issues.append(f"High CPC (${cpc:.2f})")
            elif cpc > 2:
                health_score -= 10
                warnings.append(f"Elevated CPC (${cpc:.2f})")
            
            # Check 4: Reach/Impressions ratio (delivery)
            reach = int(insight.get("reach", 0))
            impressions = int(insight.get("impressions", 0))
            if reach > 0 and impressions / reach < 1.5:
                health_score -= 15
                warnings.append("Low impression/reach ratio - Limited delivery")
            
            # Determine overall status
            if health_score >= 80:
                status = "green"
                status_label = "Healthy"
            elif health_score >= 60:
                status = "yellow"
                status_label = "Needs Attention"
            else:
                status = "red"
                status_label = "Critical Issues"
            
            health_check = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "health_score": max(0, health_score),
                "health_status": status,
                "status_label": status_label,
                "metrics": {
                    "ctr": round(ctr, 2),
                    "cpc": round(cpc, 2),
                    "cpm": round(float(insight.get("cpm", 0)), 2),
                    "frequency": round(frequency, 2),
                    "spend": round(float(insight.get("spend", 0)), 2)
                },
                "issues": issues,
                "warnings": warnings,
                "top_3_actions": []
            }
            
            # Generate top 3 prioritized actions
            if frequency > 5:
                health_check["top_3_actions"].append({
                    "priority": 1,
                    "action": "Refresh creative immediately - High frequency causing fatigue",
                    "impact": "high"
                })
            
            if ctr < 0.5:
                health_check["top_3_actions"].append({
                    "priority": 2,
                    "action": "Test new creative hooks - CTR critically low",
                    "impact": "high"
                })
            
            if cpc > 5:
                health_check["top_3_actions"].append({
                    "priority": 3,
                    "action": "Review targeting and bid strategy - CPC too high",
                    "impact": "medium"
                })
            
            # If no critical issues, suggest optimization
            if len(health_check["top_3_actions"]) == 0:
                health_check["top_3_actions"].append({
                    "priority": 1,
                    "action": "Test scaling - Performance is healthy",
                    "impact": "opportunity"
                })
            
            logger.info("campaign_health_check_complete", health_score=health_score, status=status)
            return health_check
            
        except Exception as e:
            logger.error("campaign_health_check_failed", error=str(e))
            raise MetaAPIError(f"Campaign health check failed: {str(e)}")
    
    async def detect_performance_deterioration(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "campaign",
        threshold_pct: float = 20
    ) -> Dict[str, Any]:
        """Detect performance deterioration (CTR/CPA/ROAS drops).
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Campaign/adset/ad ID
            entity_type: Type of entity
            threshold_pct: Alert threshold percentage (default: 20%)
        
        Returns:
            Performance deterioration analysis
        """
        await self._ensure_initialized()
        
        logger.info("detecting_performance_deterioration", entity_id=entity_id)
        
        try:
            # Get last 14 days, compare first 7 vs. last 7
            time_range_recent = {
                "since": (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d"),
                "until": datetime.now().strftime("%Y-%m-%d")
            }
            
            time_range_previous = {
                "since": (datetime.now() - timedelta(days=14)).strftime("%Y-%m-%d"),
                "until": (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
            }
            
            # Get both periods
            recent_insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["spend", "actions", "action_values", "ctr", "cpc"],
                time_range=time_range_recent,
                action_breakdowns=["action_type"]
            )
            
            previous_insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["spend", "actions", "action_values", "ctr", "cpc"],
                time_range=time_range_previous,
                action_breakdowns=["action_type"]
            )
            
            recent_data = recent_insights.get("data", [])
            previous_data = previous_insights.get("data", [])
            
            if not recent_data or not previous_data:
                return {
                    "deterioration_detected": False,
                    "message": "Insufficient data for comparison"
                }
            
            # Calculate metrics for both periods
            recent_metrics = self._calculate_period_metrics(recent_data)
            previous_metrics = self._calculate_period_metrics(previous_data)
            
            # Detect deterioration
            deterioration = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "comparison_periods": {
                    "recent": time_range_recent,
                    "previous": time_range_previous
                },
                "deterioration_detected": False,
                "metrics_declined": [],
                "severity": "none"
            }
            
            # Check CTR
            ctr_change = self._calculate_change_pct(recent_metrics["ctr"], previous_metrics["ctr"])
            if ctr_change < -threshold_pct:
                deterioration["deterioration_detected"] = True
                deterioration["metrics_declined"].append({
                    "metric": "CTR",
                    "recent": round(recent_metrics["ctr"], 2),
                    "previous": round(previous_metrics["ctr"], 2),
                    "change_pct": round(ctr_change, 2),
                    "severity": "high" if ctr_change < -30 else "medium"
                })
            
            # Check CPA
            cpa_change = self._calculate_change_pct(recent_metrics["cpa"], previous_metrics["cpa"])
            if cpa_change > threshold_pct and recent_metrics["cpa"] > 0:
                deterioration["deterioration_detected"] = True
                deterioration["metrics_declined"].append({
                    "metric": "CPA",
                    "recent": round(recent_metrics["cpa"], 2),
                    "previous": round(previous_metrics["cpa"], 2),
                    "change_pct": round(cpa_change, 2),
                    "severity": "high" if cpa_change > 40 else "medium"
                })
            
            # Check ROAS
            roas_change = self._calculate_change_pct(recent_metrics["roas"], previous_metrics["roas"])
            if roas_change < -threshold_pct and recent_metrics["roas"] > 0:
                deterioration["deterioration_detected"] = True
                deterioration["metrics_declined"].append({
                    "metric": "ROAS",
                    "recent": round(recent_metrics["roas"], 2),
                    "previous": round(previous_metrics["roas"], 2),
                    "change_pct": round(roas_change, 2),
                    "severity": "critical" if roas_change < -40 else "high"
                })
            
            # Determine overall severity
            if deterioration["deterioration_detected"]:
                severities = [m["severity"] for m in deterioration["metrics_declined"]]
                if "critical" in severities:
                    deterioration["severity"] = "critical"
                elif "high" in severities:
                    deterioration["severity"] = "high"
                else:
                    deterioration["severity"] = "medium"
                
                # Generate recommendations
                deterioration["recommendations"] = []
                
                if any(m["metric"] == "CTR" for m in deterioration["metrics_declined"]):
                    deterioration["recommendations"].append({
                        "action": "Test new creative immediately",
                        "reason": "CTR decline indicates creative fatigue or audience saturation"
                    })
                
                if any(m["metric"] == "CPA" for m in deterioration["metrics_declined"]):
                    deterioration["recommendations"].append({
                        "action": "Review targeting and bid strategy",
                        "reason": "CPA increase suggests competition or targeting issues"
                    })
                
                if any(m["metric"] == "ROAS" for m in deterioration["metrics_declined"]):
                    deterioration["recommendations"].append({
                        "action": "Audit conversion tracking and landing page",
                        "reason": "ROAS decline may indicate funnel issues"
                    })
            
            logger.info(
                "performance_deterioration_check_complete",
                deterioration_detected=deterioration["deterioration_detected"],
                severity=deterioration["severity"]
            )
            
            return deterioration
            
        except Exception as e:
            logger.error("performance_deterioration_detection_failed", error=str(e))
            raise MetaAPIError(f"Performance deterioration detection failed: {str(e)}")
    
    def _calculate_period_metrics(self, data: List[Dict[str, Any]]) -> Dict[str, float]:
        """Calculate aggregate metrics for a period."""
        total_spend = sum(float(d.get("spend", 0)) for d in data)
        total_ctr = sum(float(d.get("ctr", 0)) for d in data) / len(data) if data else 0
        total_cpc = sum(float(d.get("cpc", 0)) for d in data) / len(data) if data else 0
        
        # Calculate conversions and revenue
        total_conversions = 0
        total_revenue = 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))
        
        return {
            "spend": total_spend,
            "ctr": total_ctr,
            "cpc": total_cpc,
            "conversions": total_conversions,
            "revenue": total_revenue,
            "cpa": (total_spend / total_conversions) if total_conversions > 0 else 0,
            "roas": (total_revenue / total_spend) if total_spend > 0 else 0
        }
    
    async def recommend_top_5_actions(
        self,
        ad_account_id: str,
        entity_id: Optional[str] = None,
        entity_type: str = "account"
    ) -> Dict[str, Any]:
        """AI-powered: "Do these 5 things NOW" recommendations.
        
        Prioritizes actions by impact and urgency.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Specific entity ID (optional)
            entity_type: Type of entity
        
        Returns:
            Top 5 prioritized actions with estimated impact
        """
        await self._ensure_initialized()
        
        logger.info("recommending_top_5_actions", entity_type=entity_type)
        
        target_id = entity_id if entity_id else ad_account_id
        
        try:
            # Run multiple checks in parallel
            health_check_task = self.check_campaign_health_instant(ad_account_id, target_id, entity_type)
            deterioration_task = self.detect_performance_deterioration(ad_account_id, target_id, entity_type)
            
            health_check, deterioration = await asyncio.gather(
                health_check_task,
                deterioration_task,
                return_exceptions=True
            )
            
            # Collect all potential actions
            all_actions = []
            
            # From health check
            if isinstance(health_check, dict) and "top_3_actions" in health_check:
                for action in health_check["top_3_actions"]:
                    all_actions.append({
                        "action": action["action"],
                        "impact": action["impact"],
                        "urgency": "high" if health_check["health_status"] == "red" else "medium",
                        "source": "health_check"
                    })
            
            # From deterioration check
            if isinstance(deterioration, dict) and deterioration.get("deterioration_detected"):
                for rec in deterioration.get("recommendations", []):
                    all_actions.append({
                        "action": rec["action"],
                        "reason": rec["reason"],
                        "impact": "high" if deterioration["severity"] in ["critical", "high"] else "medium",
                        "urgency": deterioration["severity"],
                        "source": "deterioration_detection"
                    })
            
            # Sort by urgency and impact
            urgency_order = {"critical": 4, "high": 3, "medium": 2, "low": 1}
            impact_order = {"high": 3, "medium": 2, "low": 1, "opportunity": 1}
            
            all_actions.sort(
                key=lambda x: (urgency_order.get(x.get("urgency", "low"), 0), 
                             impact_order.get(x.get("impact", "low"), 0)),
                reverse=True
            )
            
            # Take top 5
            top_5 = all_actions[:5]
            
            recommendations = {
                "entity_id": target_id,
                "entity_type": entity_type,
                "generated_at": datetime.now().isoformat(),
                "top_5_actions": [
                    {
                        "rank": i + 1,
                        **action
                    }
                    for i, action in enumerate(top_5)
                ],
                "estimated_time_to_complete": "15-30 minutes",
                "estimated_impact": "10-30% performance improvement"
            }
            
            logger.info("top_5_actions_recommended", actions_count=len(top_5))
            return recommendations
            
        except Exception as e:
            logger.error("top_5_actions_recommendation_failed", error=str(e))
            raise MetaAPIError(f"Top 5 actions recommendation failed: {str(e)}")
    
    async def monitor_budget_burn_rate(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "campaign",
        daily_budget: Optional[float] = None
    ) -> Dict[str, Any]:
        """Monitor budget burn rate with pacing alerts.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Campaign/adset ID
            entity_type: Type of entity
            daily_budget: Daily budget (if known)
        
        Returns:
            Budget burn rate analysis with alerts
        """
        await self._ensure_initialized()
        
        logger.info("monitoring_budget_burn_rate", entity_id=entity_id)
        
        try:
            # Get today's hourly spend
            today = datetime.now().strftime("%Y-%m-%d")
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["spend"],
                breakdowns=["hourly_stats_aggregated_by_advertiser_time_zone"],
                time_range={"since": today, "until": today}
            )
            
            data = insights.get("data", [])
            
            # Calculate current spend
            current_spend = sum(float(d.get("spend", 0)) for d in data)
            current_hour = datetime.now().hour
            
            # If no budget provided, try to get it from entity
            if not daily_budget:
                if entity_type in ["campaign", "adset"]:
                    entity_data = await self.client.get(
                        f"/{entity_id}",
                        params={"fields": "daily_budget,lifetime_budget"}
                    )
                    daily_budget = float(entity_data.get("daily_budget", 0)) / 100 if entity_data.get("daily_budget") else None
            
            burn_rate_analysis = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "current_spend": round(current_spend, 2),
                "daily_budget": daily_budget,
                "current_hour": current_hour,
                "hours_remaining": 24 - current_hour,
                "pacing": {}
            }
            
            if current_hour > 0:
                avg_hourly_spend = current_spend / current_hour
                projected_eod_spend = avg_hourly_spend * 24
                
                burn_rate_analysis["pacing"] = {
                    "avg_hourly_spend": round(avg_hourly_spend, 2),
                    "projected_eod_spend": round(projected_eod_spend, 2),
                    "hourly_burn_rate": round((current_spend / current_hour), 2)
                }
                
                # Generate alerts based on budget
                if daily_budget:
                    utilization = (projected_eod_spend / daily_budget) * 100
                    burn_rate_analysis["pacing"]["budget_utilization_projected"] = round(utilization, 2)
                    
                    burn_rate_analysis["alerts"] = []
                    
                    if projected_eod_spend > daily_budget * 1.2:
                        exhaustion_hour = int((daily_budget / avg_hourly_spend)) if avg_hourly_spend > 0 else 24
                        burn_rate_analysis["alerts"].append({
                            "severity": "critical",
                            "message": f"Budget will be exhausted by {exhaustion_hour}:00",
                            "projected_overspend": round(projected_eod_spend - daily_budget, 2)
                        })
                    elif projected_eod_spend < daily_budget * 0.8:
                        burn_rate_analysis["alerts"].append({
                            "severity": "warning",
                            "message": f"Underpacing - will only spend {utilization:.0f}% of budget",
                            "projected_underspend": round(daily_budget - projected_eod_spend, 2)
                        })
                    else:
                        burn_rate_analysis["alerts"].append({
                            "severity": "info",
                            "message": "Budget pacing is healthy",
                            "utilization": round(utilization, 2)
                        })
            
            logger.info("budget_burn_rate_monitored", current_spend=current_spend)
            return burn_rate_analysis
            
        except Exception as e:
            logger.error("budget_burn_rate_monitoring_failed", error=str(e))
            raise MetaAPIError(f"Budget burn rate monitoring failed: {str(e)}")
    
    async def check_auction_competition_now(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "campaign"
    ) -> Dict[str, Any]:
        """Check real-time auction competition and CPM changes.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Campaign/adset ID
            entity_type: Type of entity
        
        Returns:
            Auction competition analysis
        """
        await self._ensure_initialized()
        
        logger.info("checking_auction_competition", entity_id=entity_id)
        
        try:
            # Get last 3 days CPM trends
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["cpm", "spend", "impressions"],
                time_increment=1,
                time_range={
                    "since": (datetime.now() - timedelta(days=3)).strftime("%Y-%m-%d"),
                    "until": datetime.now().strftime("%Y-%m-%d")
                }
            )
            
            data = insights.get("data", [])
            
            if len(data) < 2:
                return {
                    "entity_id": entity_id,
                    "competition_detected": False,
                    "message": "Insufficient data for trend analysis"
                }
            
            # Analyze CPM trend
            cpms = [float(d.get("cpm", 0)) for d in data if float(d.get("cpm", 0)) > 0]
            
            if len(cpms) < 2:
                return {
                    "entity_id": entity_id,
                    "competition_detected": False,
                    "message": "No CPM data available"
                }
            
            latest_cpm = cpms[-1]
            avg_cpm = sum(cpms[:-1]) / len(cpms[:-1])
            cpm_change_pct = ((latest_cpm - avg_cpm) / avg_cpm * 100) if avg_cpm > 0 else 0
            
            competition_analysis = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "current_cpm": round(latest_cpm, 2),
                "avg_cpm_last_3_days": round(avg_cpm, 2),
                "cpm_change_pct": round(cpm_change_pct, 2),
                "competition_level": "normal",
                "recommendations": []
            }
            
            # Detect competition increase
            if cpm_change_pct > 20:
                competition_analysis["competition_level"] = "high"
                competition_analysis["competition_detected"] = True
                competition_analysis["recommendations"].append({
                    "action": "Consider increasing bids to maintain delivery",
                    "reason": f"CPM increased {cpm_change_pct:.0f}% - heightened competition"
                })
            elif cpm_change_pct > 10:
                competition_analysis["competition_level"] = "elevated"
                competition_analysis["competition_detected"] = True
                competition_analysis["recommendations"].append({
                    "action": "Monitor bid strategy - moderate competition increase",
                    "reason": f"CPM increased {cpm_change_pct:.0f}%"
                })
            elif cpm_change_pct < -20:
                competition_analysis["competition_level"] = "low"
                competition_analysis["competition_detected"] = True
                competition_analysis["recommendations"].append({
                    "action": "Opportunity to scale - reduced competition",
                    "reason": f"CPM decreased {abs(cpm_change_pct):.0f}%"
                })
            else:
                competition_analysis["competition_detected"] = False
            
            logger.info("auction_competition_checked", competition_level=competition_analysis["competition_level"])
            return competition_analysis
            
        except Exception as e:
            logger.error("auction_competition_check_failed", error=str(e))
            raise MetaAPIError(f"Auction competition check failed: {str(e)}")
    
    async def detect_creative_fatigue_radar(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "ad"
    ) -> Dict[str, Any]:
        """Detect which creative is fatiguing RIGHT NOW.
        
        Analyzes frequency and performance degradation patterns.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Ad or adset ID
            entity_type: Type of entity (ad, adset)
        
        Returns:
            Creative fatigue analysis with urgency
        """
        await self._ensure_initialized()
        
        logger.info("detecting_creative_fatigue", entity_id=entity_id)
        
        try:
            # Get last 14 days of data with frequency breakdown
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["frequency", "ctr", "impressions", "spend", "actions"],
                time_increment=1,
                time_range={
                    "since": (datetime.now() - timedelta(days=14)).strftime("%Y-%m-%d"),
                    "until": datetime.now().strftime("%Y-%m-%d")
                }
            )
            
            data = insights.get("data", [])
            
            if len(data) < 7:
                return {
                    "entity_id": entity_id,
                    "fatigue_detected": False,
                    "message": "Insufficient data (need 7+ days)"
                }
            
            # Analyze frequency and CTR trends
            recent_data = data[-7:]  # Last 7 days
            older_data = data[:7]     # Previous 7 days
            
            recent_avg_frequency = sum(float(d.get("frequency", 0)) for d in recent_data) / len(recent_data)
            recent_avg_ctr = sum(float(d.get("ctr", 0)) for d in recent_data) / len(recent_data)
            
            older_avg_frequency = sum(float(d.get("frequency", 0)) for d in older_data) / len(older_data)
            older_avg_ctr = sum(float(d.get("ctr", 0)) for d in older_data) / len(older_data)
            
            # Calculate trends
            frequency_increase = ((recent_avg_frequency - older_avg_frequency) / older_avg_frequency * 100) if older_avg_frequency > 0 else 0
            ctr_change = ((recent_avg_ctr - older_avg_ctr) / older_avg_ctr * 100) if older_avg_ctr > 0 else 0
            
            fatigue_analysis = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "current_frequency": round(recent_avg_frequency, 2),
                "frequency_trend": round(frequency_increase, 2),
                "current_ctr": round(recent_avg_ctr, 2),
                "ctr_trend": round(ctr_change, 2),
                "fatigue_detected": False,
                "fatigue_level": "none",
                "urgency": "low",
                "recommendations": []
            }
            
            # Detect fatigue
            if recent_avg_frequency > 4 and ctr_change < -15:
                fatigue_analysis["fatigue_detected"] = True
                fatigue_analysis["fatigue_level"] = "severe"
                fatigue_analysis["urgency"] = "immediate"
                fatigue_analysis["recommendations"].append({
                    "action": "Replace creative immediately",
                    "reason": f"High frequency ({recent_avg_frequency:.1f}x) + CTR down {abs(ctr_change):.0f}%",
                    "estimated_impact": "20-40% performance recovery"
                })
            elif recent_avg_frequency > 3 and ctr_change < -10:
                fatigue_analysis["fatigue_detected"] = True
                fatigue_analysis["fatigue_level"] = "moderate"
                fatigue_analysis["urgency"] = "high"
                fatigue_analysis["recommendations"].append({
                    "action": "Refresh creative within 24-48 hours",
                    "reason": f"Moderate frequency ({recent_avg_frequency:.1f}x) + CTR declining",
                    "estimated_impact": "10-20% performance improvement"
                })
            elif recent_avg_frequency > 2.5 and ctr_change < -5:
                fatigue_analysis["fatigue_detected"] = True
                fatigue_analysis["fatigue_level"] = "early"
                fatigue_analysis["urgency"] = "medium"
                fatigue_analysis["recommendations"].append({
                    "action": "Plan creative refresh for next week",
                    "reason": "Early signs of fatigue detected",
                    "estimated_impact": "Prevent future decline"
                })
            
            logger.info("creative_fatigue_detected", fatigue_level=fatigue_analysis["fatigue_level"])
            return fatigue_analysis
            
        except Exception as e:
            logger.error("creative_fatigue_detection_failed", error=str(e))
            raise MetaAPIError(f"Creative fatigue detection failed: {str(e)}")
    
    async def track_conversion_rate_realtime(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "campaign",
        conversion_event: str = "Purchase"
    ) -> Dict[str, Any]:
        """Track real-time conversion rate by campaign.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Campaign/adset/ad ID
            entity_type: Type of entity
            conversion_event: Conversion event to track
        
        Returns:
            Real-time CVR tracking with alerts
        """
        await self._ensure_initialized()
        
        logger.info("tracking_conversion_rate", entity_id=entity_id)
        
        try:
            # Get today's data
            today = datetime.now().strftime("%Y-%m-%d")
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["clicks", "actions", "spend"],
                time_range={"since": today, "until": today},
                action_breakdowns=["action_type"]
            )
            
            # Get yesterday's data for comparison
            yesterday = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
            insights_yesterday = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["clicks", "actions", "spend"],
                time_range={"since": yesterday, "until": yesterday},
                action_breakdowns=["action_type"]
            )
            
            # Calculate today's CVR
            today_data = insights.get("data", [])
            today_clicks = sum(int(d.get("clicks", 0)) for d in today_data)
            today_conversions = 0
            today_spend = sum(float(d.get("spend", 0)) for d in today_data)
            
            for insight in today_data:
                actions = insight.get("actions", [])
                for action in actions:
                    if action.get("action_type") == conversion_event.lower():
                        today_conversions += int(action.get("value", 0))
            
            today_cvr = (today_conversions / today_clicks * 100) if today_clicks > 0 else 0
            today_cpa = (today_spend / today_conversions) if today_conversions > 0 else 0
            
            # Calculate yesterday's CVR
            yesterday_data = insights_yesterday.get("data", [])
            yesterday_clicks = sum(int(d.get("clicks", 0)) for d in yesterday_data)
            yesterday_conversions = 0
            
            for insight in yesterday_data:
                actions = insight.get("actions", [])
                for action in actions:
                    if action.get("action_type") == conversion_event.lower():
                        yesterday_conversions += int(action.get("value", 0))
            
            yesterday_cvr = (yesterday_conversions / yesterday_clicks * 100) if yesterday_clicks > 0 else 0
            
            cvr_tracking = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "conversion_event": conversion_event,
                "timestamp": datetime.now().isoformat(),
                "today": {
                    "clicks": today_clicks,
                    "conversions": today_conversions,
                    "cvr": round(today_cvr, 2),
                    "cpa": round(today_cpa, 2),
                    "spend": round(today_spend, 2)
                },
                "yesterday": {
                    "clicks": yesterday_clicks,
                    "conversions": yesterday_conversions,
                    "cvr": round(yesterday_cvr, 2)
                },
                "change": {
                    "cvr_change_pct": self._calculate_change_pct(today_cvr, yesterday_cvr)
                },
                "alerts": []
            }
            
            # Generate alerts
            if abs(cvr_tracking["change"]["cvr_change_pct"]) > 25:
                cvr_tracking["alerts"].append({
                    "severity": "high",
                    "message": f"CVR changed {cvr_tracking['change']['cvr_change_pct']:.0f}% vs. yesterday",
                    "action": "Investigate landing page or funnel changes"
                })
            
            if today_cvr < 1 and today_clicks > 100:
                cvr_tracking["alerts"].append({
                    "severity": "warning",
                    "message": f"Low CVR ({today_cvr:.2f}%) with significant traffic",
                    "action": "Review landing page experience and offer"
                })
            
            logger.info("conversion_rate_tracked", today_cvr=today_cvr)
            return cvr_tracking
            
        except Exception as e:
            logger.error("conversion_rate_tracking_failed", error=str(e))
            raise MetaAPIError(f"Conversion rate tracking failed: {str(e)}")
    
    async def measure_audience_exhaustion(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "adset"
    ) -> Dict[str, Any]:
        """Measure audience exhaustion meter - days until saturation.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Adset or campaign ID
            entity_type: Type of entity
        
        Returns:
            Audience exhaustion analysis with timeline
        """
        await self._ensure_initialized()
        
        logger.info("measuring_audience_exhaustion", entity_id=entity_id)
        
        try:
            # Get audience size and current reach
            if entity_type == "adset":
                await self.client.get(
                    f"/{entity_id}",
                    params={"fields": "targeting"}
                )
            
            # Get reach and frequency data
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["reach", "frequency", "impressions", "spend"],
                time_range={
                    "since": (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d"),
                    "until": datetime.now().strftime("%Y-%m-%d")
                }
            )
            
            data = insights.get("data", [])
            if not data:
                return {
                    "entity_id": entity_id,
                    "exhaustion_detected": False,
                    "message": "No data available"
                }
            
            insight = data[0]
            current_reach = int(insight.get("reach", 0))
            current_frequency = float(insight.get("frequency", 0))
            int(insight.get("impressions", 0))
            
            # Estimate audience size (rough approximation)
            estimated_audience_size = current_reach * 3  # Conservative multiplier
            
            # Calculate exhaustion metrics
            reach_percentage = (current_reach / estimated_audience_size * 100) if estimated_audience_size > 0 else 0
            
            exhaustion_analysis = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "current_reach": current_reach,
                "estimated_audience_size": estimated_audience_size,
                "reach_percentage": round(reach_percentage, 2),
                "current_frequency": round(current_frequency, 2),
                "exhaustion_level": "low",
                "days_until_saturation": None,
                "recommendations": []
            }
            
            # Determine exhaustion level
            if reach_percentage > 60 or current_frequency > 4:
                exhaustion_analysis["exhaustion_level"] = "high"
                exhaustion_analysis["days_until_saturation"] = 3
                exhaustion_analysis["recommendations"].append({
                    "action": "Expand audience immediately",
                    "reason": f"Reached {reach_percentage:.0f}% of audience with {current_frequency:.1f}x frequency",
                    "suggestions": [
                        "Create lookalike audiences",
                        "Expand interest targeting",
                        "Test new geographic markets"
                    ]
                })
            elif reach_percentage > 40 or current_frequency > 3:
                exhaustion_analysis["exhaustion_level"] = "medium"
                exhaustion_analysis["days_until_saturation"] = 7
                exhaustion_analysis["recommendations"].append({
                    "action": "Plan audience expansion within 1 week",
                    "reason": f"Approaching saturation at {reach_percentage:.0f}% reach",
                    "suggestions": [
                        "Test broader targeting",
                        "Add interest layers",
                        "Consider CBO for automatic allocation"
                    ]
                })
            elif reach_percentage > 25 or current_frequency > 2:
                exhaustion_analysis["exhaustion_level"] = "low"
                exhaustion_analysis["days_until_saturation"] = 14
                exhaustion_analysis["recommendations"].append({
                    "action": "Monitor for next 2 weeks",
                    "reason": "Healthy reach/frequency balance",
                    "suggestions": ["Continue current strategy"]
                })
            else:
                exhaustion_analysis["exhaustion_level"] = "none"
                exhaustion_analysis["days_until_saturation"] = 30
                exhaustion_analysis["recommendations"].append({
                    "action": "Consider scaling budget",
                    "reason": "Plenty of audience headroom",
                    "suggestions": ["Test 20-50% budget increase"]
                })
            
            logger.info("audience_exhaustion_measured", exhaustion_level=exhaustion_analysis["exhaustion_level"])
            return exhaustion_analysis
            
        except Exception as e:
            logger.error("audience_exhaustion_measurement_failed", error=str(e))
            raise MetaAPIError(f"Audience exhaustion measurement failed: {str(e)}")
    
    async def track_learning_phase(
        self,
        ad_account_id: str,
        entity_id: str,
        entity_type: str = "adset"
    ) -> Dict[str, Any]:
        """Track learning phase status and provide recommendations.
        
        Args:
            ad_account_id: Meta ad account ID
            entity_id: Adset or campaign ID
            entity_type: Type of entity
        
        Returns:
            Learning phase tracking with edit recommendations
        """
        await self._ensure_initialized()
        
        logger.info("tracking_learning_phase", entity_id=entity_id)
        
        try:
            # Get delivery status
            if entity_type == "adset":
                adset_data = await self.client.get(
                    f"/{entity_id}",
                    params={"fields": "id,name,status,effective_status,configured_status"}
                )
                
                status = adset_data.get("effective_status", "UNKNOWN")
            else:
                status = "UNKNOWN"
            
            # Get recent performance to estimate learning phase
            insights = await self.client.get_insights(
                object_id=entity_id,
                level=entity_type,
                fields=["actions", "spend"],
                time_range={
                    "since": (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d"),
                    "until": datetime.now().strftime("%Y-%m-%d")
                },
                action_breakdowns=["action_type"]
            )
            
            data = insights.get("data", [])
            
            # Count conversions
            total_conversions = 0
            for insight in data:
                actions = insight.get("actions", [])
                for action in actions:
                    # Count optimization events
                    if action.get("action_type") in ["purchase", "lead", "complete_registration"]:
                        total_conversions += int(action.get("value", 0))
            
            learning_tracking = {
                "entity_id": entity_id,
                "entity_type": entity_type,
                "delivery_status": status,
                "conversions_in_7_days": total_conversions,
                "estimated_learning_phase": "unknown",
                "exit_prediction": None,
                "edit_recommendations": [],
                "warnings": []
            }
            
            # Determine learning phase status
            # Meta typically needs 50 conversions per week to exit learning
            if total_conversions >= 50:
                learning_tracking["estimated_learning_phase"] = "completed"
                learning_tracking["edit_recommendations"].append({
                    "safe_to_edit": True,
                    "message": "Out of learning phase - safe to make optimizations",
                    "suggested_edits": [
                        "Adjust targeting",
                        "Test new creative",
                        "Modify budget"
                    ]
                })
            elif total_conversions >= 30:
                learning_tracking["estimated_learning_phase"] = "near_completion"
                learning_tracking["exit_prediction"] = "2-3 days"
                learning_tracking["warnings"].append({
                    "message": "Close to exiting learning - avoid major changes",
                    "reason": f"{total_conversions}/50 conversions"
                })
            elif total_conversions >= 15:
                learning_tracking["estimated_learning_phase"] = "in_progress"
                learning_tracking["exit_prediction"] = "4-7 days"
                learning_tracking["warnings"].append({
                    "message": "In learning phase - minimize edits",
                    "reason": f"{total_conversions}/50 conversions"
                })
            else:
                learning_tracking["estimated_learning_phase"] = "early"
                learning_tracking["exit_prediction"] = ">7 days"
                learning_tracking["warnings"].append({
                    "message": "Early learning phase - DO NOT EDIT",
                    "reason": f"Only {total_conversions}/50 conversions"
                })
                learning_tracking["edit_recommendations"].append({
                    "safe_to_edit": False,
                    "message": "Any edit will reset learning phase",
                    "action": "Wait at least 3-5 days before making changes"
                })
            
            logger.info("learning_phase_tracked", phase=learning_tracking["estimated_learning_phase"])
            return learning_tracking
            
        except Exception as e:
            logger.error("learning_phase_tracking_failed", error=str(e))
            raise MetaAPIError(f"Learning phase tracking failed: {str(e)}")

