"""
Audience Intelligence Module for Meta Ads MCP Server

This module provides advanced audience analysis and targeting optimization tools
that enable LLMs to identify high-value segments and optimize audience strategies.
"""

from typing import Dict, List, Optional
from datetime import datetime, timedelta
from dataclasses import dataclass
import statistics

from .meta_client import MetaClient
from .schemas import (
    AudienceSaturationRequest,
    AudienceSaturationResponse,
    DemographicProfilerRequest,
    DemographicProfilerResponse,
    InterestLayerRequest,
    InterestLayerResponse,
    LookalikeQualityRequest,
    LookalikeQualityResponse,
    AudienceOverlapHeatmapRequest,
    AudienceOverlapHeatmapResponse,
    CustomAudienceHealthRequest,
    CustomAudienceHealthResponse,
    GeographicPerformanceRequest,
    GeographicPerformanceResponse,
    BehaviorTargetingRequest,
    BehaviorTargetingResponse,
)
from .logging import get_logger

logger = get_logger(__name__)


@dataclass
class AudienceContext:
    """Context for audience analysis operations"""
    ad_account_id: str
    time_range: Dict[str, str]
    audience_id: Optional[str] = None


class AudienceIntelligenceEngine:
    """Handles advanced audience intelligence operations for Meta Ads"""
    
    def __init__(self, client: MetaClient):
        self.client = client
    
    async def detect_audience_saturation(
        self, 
        request: AudienceSaturationRequest
    ) -> AudienceSaturationResponse:
        """
        Detect audience saturation and identify expansion opportunities.
        
        Analyzes reach vs addressable market to determine saturation level
        and calculates growth runway.
        """
        try:
            # Get audience reach data
            insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "reach,frequency,impressions,unique_clicks,unique_ctr",
                    "level": request.entity_type
                }
            )
            
            data = insights.get("data", [{}])[0]
            
            # Get audience size estimate
            audience_info = await self.client.get(
                request.entity_id,
                params={
                    "fields": "targeting,promoted_object"
                }
            )
            
            # Estimate addressable market (simplified)
            estimated_audience_size = await self._estimate_audience_size(
                audience_info.get("targeting", {}),
                request.ad_account_id
            )
            
            # Calculate saturation metrics
            current_reach = int(data.get("reach", 0))
            frequency = float(data.get("frequency", 0))
            
            saturation_metrics = {
                "current_reach": current_reach,
                "estimated_addressable_market": estimated_audience_size,
                "reach_percentage": round((current_reach / estimated_audience_size * 100), 2) if estimated_audience_size > 0 else 0,
                "average_frequency": frequency,
                "saturation_score": self._calculate_saturation_score(current_reach, estimated_audience_size, frequency),
                "saturation_level": self._determine_saturation_level(current_reach, estimated_audience_size, frequency)
            }
            
            # Identify expansion opportunities
            expansion_opportunities = await self._identify_expansion_opportunities(
                audience_info.get("targeting", {}),
                saturation_metrics
            )
            
            # Calculate growth runway
            growth_runway = {
                "remaining_reach": estimated_audience_size - current_reach,
                "growth_potential_percentage": round(((estimated_audience_size - current_reach) / current_reach * 100), 2) if current_reach > 0 else 0,
                "estimated_days_to_saturation": self._estimate_days_to_saturation(saturation_metrics),
                "recommended_expansion_timing": "immediate" if saturation_metrics["saturation_score"] > 0.7 else "monitor"
            }
            
            # Generate recommendations
            recommendations = self._generate_saturation_recommendations(
                saturation_metrics, expansion_opportunities, growth_runway
            )
            
            return AudienceSaturationResponse(
                saturation_metrics=saturation_metrics,
                expansion_opportunities=expansion_opportunities,
                growth_runway=growth_runway,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error detecting audience saturation: {e}")
            raise
    
    async def profile_demographics(
        self, 
        request: DemographicProfilerRequest
    ) -> DemographicProfilerResponse:
        """
        Detailed demographic performance profiling.
        
        Identifies high-value demographics and provides targeting refinement
        recommendations.
        """
        try:
            # Get demographic breakdown
            insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "spend,conversions,cpa,roas,ctr,frequency",
                    "breakdowns": "age,gender,country",
                    "level": request.entity_type
                }
            )
            
            segments = insights.get("data", [])
            
            # Profile each demographic segment
            demographic_profiles = []
            
            for segment in segments:
                profile = {
                    "age": segment.get("age", "unknown"),
                    "gender": segment.get("gender", "unknown"),
                    "country": segment.get("country", "unknown"),
                    "spend": float(segment.get("spend", 0)),
                    "conversions": int(segment.get("conversions", 0)),
                    "cpa": float(segment.get("cpa", 0)),
                    "roas": float(segment.get("roas", 0)),
                    "ctr": float(segment.get("ctr", 0)),
                    "performance_score": self._calculate_demographic_performance_score(segment),
                    "value_tier": self._determine_value_tier(segment),
                    "index": self._calculate_demographic_index(segment, segments)
                }
                demographic_profiles.append(profile)
            
            # Identify high-value demographics
            high_value_segments = [
                seg for seg in demographic_profiles 
                if seg["value_tier"] in ["premium", "high_value"]
            ]
            
            # Identify underperforming segments
            underperforming_segments = [
                seg for seg in demographic_profiles
                if seg["value_tier"] in ["low_value", "poor"]
            ]
            
            # Generate targeting refinements
            targeting_refinements = self._generate_targeting_refinements(
                high_value_segments, underperforming_segments
            )
            
            # Generate recommendations
            recommendations = self._generate_demographic_recommendations(
                high_value_segments, underperforming_segments, targeting_refinements
            )
            
            return DemographicProfilerResponse(
                demographic_profiles=demographic_profiles,
                high_value_segments=high_value_segments,
                underperforming_segments=underperforming_segments,
                targeting_refinements=targeting_refinements,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error profiling demographics: {e}")
            raise
    
    async def analyze_interest_layers(
        self, 
        request: InterestLayerRequest
    ) -> InterestLayerResponse:
        """
        Analyze interest targeting effectiveness.
        
        Evaluates interest combinations and provides expansion/pruning recommendations.
        """
        try:
            # Get current targeting
            entity_info = await self.client.get(
                request.entity_id,
                params={
                    "fields": "targeting"
                }
            )
            
            targeting = entity_info.get("targeting", {})
            interests = targeting.get("flexible_spec", [{}])[0].get("interests", [])
            
            # Get performance data
            insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "spend,conversions,cpa,roas"
                }
            )
            
            overall_performance = insights.get("data", [{}])[0]
            
            # Analyze interest performance (simplified - would need detailed breakdown in production)
            interest_analysis = []
            
            for interest in interests:
                interest_performance = {
                    "interest_id": interest.get("id"),
                    "interest_name": interest.get("name"),
                    "estimated_performance_index": self._estimate_interest_performance(interest, overall_performance),
                    "audience_size_estimate": await self._get_interest_audience_size(interest, request.ad_account_id),
                    "recommendation": "keep"  # Would be more sophisticated in production
                }
                interest_analysis.append(interest_performance)
            
            # Analyze interest overlaps
            interest_overlaps = await self._analyze_interest_overlaps(interests, request.ad_account_id)
            
            # Generate expansion suggestions
            expansion_suggestions = await self._suggest_interest_expansions(
                interests, interest_analysis, request.ad_account_id
            )
            
            # Generate pruning recommendations
            pruning_recommendations = self._recommend_interest_pruning(
                interest_analysis, interest_overlaps
            )
            
            # Generate recommendations
            recommendations = self._generate_interest_recommendations(
                interest_analysis, expansion_suggestions, pruning_recommendations
            )
            
            return InterestLayerResponse(
                interest_analysis=interest_analysis,
                interest_overlaps=interest_overlaps,
                expansion_suggestions=expansion_suggestions,
                pruning_recommendations=pruning_recommendations,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error analyzing interest layers: {e}")
            raise
    
    async def score_lookalike_quality(
        self, 
        request: LookalikeQualityRequest
    ) -> LookalikeQualityResponse:
        """
        Score lookalike audience quality and effectiveness.
        
        Compares LAL performance vs source audience and recommends optimal percentage.
        """
        try:
            # Get lookalike audience performance
            lal_insights = await self.client.get(
                f"{request.lookalike_audience_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "reach,spend,conversions,cpa,roas,ctr",
                    "level": "audience"
                }
            )
            
            lal_performance = lal_insights.get("data", [{}])[0]
            
            # Get source audience performance if available
            source_performance = {}
            if request.source_audience_id:
                source_insights = await self.client.get(
                    f"{request.source_audience_id}/insights",
                    params={
                        "time_range": request.time_range,
                        "fields": "reach,spend,conversions,cpa,roas,ctr",
                        "level": "audience"
                    }
                )
                source_performance = source_insights.get("data", [{}])[0]
            
            # Calculate quality metrics
            quality_metrics = {
                "lal_reach": int(lal_performance.get("reach", 0)),
                "lal_cpa": float(lal_performance.get("cpa", 0)),
                "lal_roas": float(lal_performance.get("roas", 0)),
                "lal_ctr": float(lal_performance.get("ctr", 0)),
                "source_cpa": float(source_performance.get("cpa", 0)) if source_performance else 0,
                "source_roas": float(source_performance.get("roas", 0)) if source_performance else 0,
                "quality_score": self._calculate_lal_quality_score(lal_performance, source_performance),
                "similarity_score": self._calculate_similarity_score(lal_performance, source_performance)
            }
            
            # Determine optimal LAL percentage
            optimal_percentage = self._determine_optimal_lal_percentage(
                quality_metrics, request.current_lal_percentage
            )
            
            # Analyze seed audience quality
            seed_analysis = await self._analyze_seed_quality(
                request.source_audience_id, source_performance
            )
            
            # Generate expansion recommendations
            expansion_recommendations = self._generate_lal_expansion_recommendations(
                quality_metrics, optimal_percentage, seed_analysis
            )
            
            # Generate recommendations
            recommendations = self._generate_lookalike_recommendations(
                quality_metrics, optimal_percentage, seed_analysis, expansion_recommendations
            )
            
            return LookalikeQualityResponse(
                quality_metrics=quality_metrics,
                optimal_percentage=optimal_percentage,
                seed_analysis=seed_analysis,
                expansion_recommendations=expansion_recommendations,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error scoring lookalike quality: {e}")
            raise
    
    async def map_audience_overlap(
        self, 
        request: AudienceOverlapHeatmapRequest
    ) -> AudienceOverlapHeatmapResponse:
        """
        Create audience overlap heatmap across campaigns.
        
        Identifies audience duplication and provides consolidation recommendations.
        """
        try:
            # Get all audiences being used
            campaigns_audiences = []
            
            for campaign_id in request.campaign_ids:
                campaign_info = await self.client.get(
                    f"{campaign_id}/adsets",
                    params={
                        "fields": "name,targeting"
                    }
                )
                
                for adset in campaign_info.get("data", []):
                    campaigns_audiences.append({
                        "campaign_id": campaign_id,
                        "adset_id": adset["id"],
                        "adset_name": adset.get("name", "Unknown"),
                        "targeting": adset.get("targeting", {})
                    })
            
            # Calculate overlaps between all pairs
            overlap_matrix = []
            
            for i, audience1 in enumerate(campaigns_audiences):
                for audience2 in campaigns_audiences[i+1:]:
                    overlap = await self._calculate_audience_overlap(
                        audience1, audience2, request.ad_account_id
                    )
                    
                    if overlap["overlap_percentage"] > request.min_overlap_threshold:
                        overlap_matrix.append({
                            "adset1_id": audience1["adset_id"],
                            "adset1_name": audience1["adset_name"],
                            "adset2_id": audience2["adset_id"],
                            "adset2_name": audience2["adset_name"],
                            "overlap_percentage": overlap["overlap_percentage"],
                            "overlap_size": overlap["overlap_size"],
                            "cannibalization_risk": self._assess_cannibalization_risk(overlap)
                        })
            
            # Sort by overlap percentage
            overlap_matrix.sort(key=lambda x: x["overlap_percentage"], reverse=True)
            
            # Generate consolidation opportunities
            consolidation_opportunities = self._identify_consolidation_opportunities(
                overlap_matrix
            )
            
            # Generate exclusion recommendations
            exclusion_recommendations = self._generate_exclusion_recommendations(
                overlap_matrix, consolidation_opportunities
            )
            
            # Generate recommendations
            recommendations = self._generate_overlap_recommendations(
                overlap_matrix, consolidation_opportunities, exclusion_recommendations
            )
            
            return AudienceOverlapHeatmapResponse(
                overlap_matrix=overlap_matrix,
                consolidation_opportunities=consolidation_opportunities,
                exclusion_recommendations=exclusion_recommendations,
                recommendations=recommendations,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error mapping audience overlap: {e}")
            raise
    
    async def monitor_custom_audience_health(
        self, 
        request: CustomAudienceHealthRequest
    ) -> CustomAudienceHealthResponse:
        """
        Monitor custom audience list quality and health.
        
        Tracks match rates, size trends, and provides refresh recommendations.
        """
        try:
            # Get custom audience info
            audience_info = await self.client.get(
                request.custom_audience_id,
                params={
                    "fields": "name,approximate_count,delivery_status,operation_status,time_updated,subtype"
                }
            )
            
            # Calculate health metrics
            health_metrics = {
                "audience_size": int(audience_info.get("approximate_count", 0)),
                "last_updated": audience_info.get("time_updated"),
                "days_since_update": self._calculate_days_since_update(audience_info.get("time_updated")),
                "delivery_status": audience_info.get("delivery_status", {}).get("status"),
                "estimated_match_rate": self._estimate_match_rate(audience_info),
                "health_score": self._calculate_audience_health_score(audience_info),
                "health_status": self._determine_health_status(audience_info)
            }
            
            # Analyze size trends
            size_trends = await self._analyze_audience_size_trends(
                request.custom_audience_id, request.lookback_days
            )
            
            # Calculate refresh frequency
            refresh_optimization = {
                "current_refresh_frequency": f"every {health_metrics['days_since_update']} days",
                "optimal_refresh_frequency": self._calculate_optimal_refresh_frequency(health_metrics, size_trends),
                "next_recommended_refresh": self._calculate_next_refresh_date(health_metrics)
            }
            
            # Assess data quality
            data_quality_assessment = {
                "match_rate_quality": "good" if health_metrics["estimated_match_rate"] > 0.5 else "needs_improvement",
                "size_stability": "stable" if size_trends.get("volatility", 0) < 0.2 else "volatile",
                "freshness_score": self._calculate_freshness_score(health_metrics["days_since_update"]),
                "overall_quality": health_metrics["health_status"]
            }
            
            # Generate recommendations
            recommendations = self._generate_audience_health_recommendations(
                health_metrics, size_trends, refresh_optimization, data_quality_assessment
            )
            
            return CustomAudienceHealthResponse(
                health_metrics=health_metrics,
                size_trends=size_trends,
                refresh_optimization=refresh_optimization,
                data_quality_assessment=data_quality_assessment,
                recommendations=recommendations,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error monitoring custom audience health: {e}")
            raise
    
    async def deep_dive_geographic_performance(
        self, 
        request: GeographicPerformanceRequest
    ) -> GeographicPerformanceResponse:
        """
        Deep dive into geographic performance for location optimization.
        
        Analyzes country/state/city performance and provides expansion recommendations.
        """
        try:
            # Get geographic breakdown
            insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "spend,conversions,cpa,roas,impressions,reach",
                    "breakdowns": "country,region,dma",
                    "level": request.entity_type
                }
            )
            
            locations = insights.get("data", [])
            
            # Analyze each location
            location_analysis = []
            
            for location in locations:
                analysis = {
                    "country": location.get("country", "Unknown"),
                    "region": location.get("region", "Unknown"),
                    "dma": location.get("dma", "Unknown"),
                    "spend": float(location.get("spend", 0)),
                    "conversions": int(location.get("conversions", 0)),
                    "cpa": float(location.get("cpa", 0)),
                    "roas": float(location.get("roas", 0)),
                    "reach": int(location.get("reach", 0)),
                    "performance_tier": self._determine_location_tier(location),
                    "market_potential": self._estimate_market_potential(location),
                    "expansion_priority": self._calculate_expansion_priority(location)
                }
                location_analysis.append(analysis)
            
            # Sort by performance
            location_analysis.sort(key=lambda x: x["roas"], reverse=True)
            
            # Identify top markets
            top_markets = location_analysis[:5]
            
            # Identify expansion opportunities
            expansion_opportunities = [
                loc for loc in location_analysis
                if loc["market_potential"] == "high" and loc["spend"] < 100
            ]
            
            # Generate geographic recommendations
            geographic_recommendations = self._generate_geographic_expansion_recommendations(
                location_analysis, top_markets, expansion_opportunities
            )
            
            # Generate recommendations
            recommendations = self._generate_location_recommendations(
                location_analysis, top_markets, expansion_opportunities, geographic_recommendations
            )
            
            return GeographicPerformanceResponse(
                location_analysis=location_analysis,
                top_markets=top_markets,
                expansion_opportunities=expansion_opportunities,
                geographic_recommendations=geographic_recommendations,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error analyzing geographic performance: {e}")
            raise
    
    async def optimize_behavior_targeting(
        self, 
        request: BehaviorTargetingRequest
    ) -> BehaviorTargetingResponse:
        """
        Optimize behavioral targeting layers.
        
        Analyzes behavior targeting effectiveness and suggests combinations.
        """
        try:
            # Get current behavior targeting
            entity_info = await self.client.get(
                request.entity_id,
                params={
                    "fields": "targeting"
                }
            )
            
            targeting = entity_info.get("targeting", {})
            behaviors = targeting.get("behaviors", [])
            
            # Get performance data
            insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "spend,conversions,cpa,roas,ctr"
                }
            )
            
            overall_performance = insights.get("data", [{}])[0]
            
            # Analyze behavior effectiveness
            behavior_analysis = []
            
            for behavior in behaviors:
                analysis = {
                    "behavior_id": behavior.get("id"),
                    "behavior_name": behavior.get("name"),
                    "effectiveness_score": self._calculate_behavior_effectiveness(behavior, overall_performance),
                    "audience_size_impact": await self._estimate_behavior_audience_impact(behavior, request.ad_account_id),
                    "recommendation": "keep"  # Would be more sophisticated
                }
                behavior_analysis.append(analysis)
            
            # Analyze device usage patterns
            device_insights = await self.client.get(
                f"{request.entity_id}/insights",
                params={
                    "time_range": request.time_range,
                    "fields": "spend,conversions,cpa",
                    "breakdowns": "impression_device",
                    "level": request.entity_type
                }
            )
            
            device_patterns = device_insights.get("data", [])
            
            # Analyze purchase behaviors
            purchase_behavior_analysis = self._analyze_purchase_behaviors(
                behaviors, overall_performance
            )
            
            # Suggest behavior combinations
            combination_suggestions = await self._suggest_behavior_combinations(
                behaviors, behavior_analysis, request.ad_account_id
            )
            
            # Generate recommendations
            recommendations = self._generate_behavior_recommendations(
                behavior_analysis, purchase_behavior_analysis, combination_suggestions
            )
            
            return BehaviorTargetingResponse(
                behavior_analysis=behavior_analysis,
                device_patterns=[{
                    "device": d.get("impression_device"),
                    "spend": float(d.get("spend", 0)),
                    "conversions": int(d.get("conversions", 0)),
                    "cpa": float(d.get("cpa", 0))
                } for d in device_patterns],
                purchase_behavior_analysis=purchase_behavior_analysis,
                combination_suggestions=combination_suggestions,
                recommendations=recommendations,
                time_range=request.time_range,
                generated_at=datetime.utcnow()
            )
            
        except Exception as e:
            logger.error(f"Error optimizing behavior targeting: {e}")
            raise
    
    # Helper methods
    
    async def _estimate_audience_size(self, targeting: Dict, ad_account_id: str) -> int:
        """Estimate total addressable audience size"""
        # Simplified estimation - would use Targeting Insights API in production
        return 1000000  # Default estimate
    
    def _calculate_saturation_score(self, reach: int, market_size: int, frequency: float) -> float:
        """Calculate audience saturation score (0-1)"""
        if market_size == 0:
            return 0.0
        
        reach_saturation = reach / market_size
        frequency_saturation = min(1.0, frequency / 10)  # Frequency above 10 is very high
        
        # Combined score
        return round((reach_saturation * 0.6 + frequency_saturation * 0.4), 2)
    
    def _determine_saturation_level(self, reach: int, market_size: int, frequency: float) -> str:
        """Determine saturation level"""
        score = self._calculate_saturation_score(reach, market_size, frequency)
        
        if score >= 0.8:
            return "critical"
        elif score >= 0.6:
            return "high"
        elif score >= 0.4:
            return "moderate"
        else:
            return "low"
    
    async def _identify_expansion_opportunities(self, targeting: Dict, metrics: Dict) -> List[Dict]:
        """Identify audience expansion opportunities"""
        opportunities = []
        
        if metrics["saturation_score"] > 0.6:
            opportunities.append({
                "opportunity": "lookalike_expansion",
                "description": "Create 1-2% lookalike audiences from converters",
                "potential_reach_increase": "50-100%"
            })
            
            opportunities.append({
                "opportunity": "interest_expansion",
                "description": "Add related interest categories",
                "potential_reach_increase": "30-60%"
            })
            
            opportunities.append({
                "opportunity": "geographic_expansion",
                "description": "Expand to similar markets",
                "potential_reach_increase": "40-80%"
            })
        
        return opportunities
    
    def _estimate_days_to_saturation(self, metrics: Dict) -> int:
        """Estimate days until full saturation"""
        if metrics["saturation_score"] >= 0.9:
            return 0  # Already saturated
        
        # Simple linear projection
        remaining_saturation = 1.0 - metrics["saturation_score"]
        days_to_saturate = int(remaining_saturation * 30)  # Assume 30 days per 1.0 saturation point
        
        return days_to_saturate
    
    def _generate_saturation_recommendations(
        self, metrics: Dict, opportunities: List[Dict], runway: Dict
    ) -> List[Dict]:
        """Generate saturation-based recommendations"""
        recommendations = []
        
        if metrics["saturation_level"] in ["high", "critical"]:
            recommendations.append({
                "priority": "high",
                "action": "Implement audience expansion immediately",
                "rationale": f"Saturation at {metrics['saturation_score']*100:.0f}%",
                "opportunities": [opp["opportunity"] for opp in opportunities[:2]]
            })
        
        if runway["estimated_days_to_saturation"] < 14:
            recommendations.append({
                "priority": "high",
                "action": "Prepare expansion campaigns now",
                "rationale": f"Only {runway['estimated_days_to_saturation']} days until saturation"
            })
        
        return recommendations
    
    def _calculate_demographic_performance_score(self, segment: Dict) -> float:
        """Calculate performance score for demographic segment"""
        roas = float(segment.get("roas", 0))
        ctr = float(segment.get("ctr", 0))
        conversions = int(segment.get("conversions", 0))
        spend = float(segment.get("spend", 1))
        
        # Weighted score
        score = (
            roas * 0.4 +
            ctr * 20 * 0.3 +
            (conversions / spend) * 10 * 0.3
        )
        
        return round(score, 2)
    
    def _determine_value_tier(self, segment: Dict) -> str:
        """Determine value tier for segment"""
        score = self._calculate_demographic_performance_score(segment)
        
        if score >= 4.0:
            return "premium"
        elif score >= 3.0:
            return "high_value"
        elif score >= 2.0:
            return "medium_value"
        elif score >= 1.0:
            return "low_value"
        else:
            return "poor"
    
    def _calculate_demographic_index(self, segment: Dict, all_segments: List[Dict]) -> float:
        """Calculate performance index vs average"""
        segment_roas = float(segment.get("roas", 0))
        
        all_roas = [float(s.get("roas", 0)) for s in all_segments if s.get("roas")]
        avg_roas = statistics.mean(all_roas) if all_roas else 1
        
        if avg_roas == 0:
            return 1.0
        
        return round(segment_roas / avg_roas, 2)
    
    def _generate_targeting_refinements(
        self, high_value: List[Dict], underperforming: List[Dict]
    ) -> Dict:
        """Generate targeting refinement suggestions"""
        return {
            "focus_demographics": [
                f"{seg['age']}-{seg['gender']}-{seg['country']}"
                for seg in high_value[:3]
            ],
            "exclude_demographics": [
                f"{seg['age']}-{seg['gender']}-{seg['country']}"
                for seg in underperforming[:3]
            ],
            "potential_savings": sum(seg["spend"] for seg in underperforming[:3])
        }
    
    def _generate_demographic_recommendations(
        self, high_value: List[Dict], underperforming: List[Dict], refinements: Dict
    ) -> List[Dict]:
        """Generate demographic optimization recommendations"""
        recommendations = []
        
        if high_value:
            recommendations.append({
                "priority": "high",
                "action": "Create dedicated campaigns for top 3 demographics",
                "segments": refinements["focus_demographics"],
                "expected_lift": "25-40%"
            })
        
        if underperforming:
            recommendations.append({
                "priority": "high",
                "action": "Exclude or reduce budget for poor-performing demographics",
                "potential_savings": f"${refinements['potential_savings']:.2f}"
            })
        
        return recommendations
    
    def _estimate_interest_performance(self, interest: Dict, overall: Dict) -> float:
        """Estimate interest performance index"""
        # Simplified - would need detailed breakdown
        return 1.0
    
    async def _get_interest_audience_size(self, interest: Dict, ad_account_id: str) -> int:
        """Get estimated audience size for interest"""
        # Would use Targeting Insights API
        return 500000
    
    async def _analyze_interest_overlaps(self, interests: List[Dict], ad_account_id: str) -> List[Dict]:
        """Analyze overlaps between interests"""
        # Simplified
        return []
    
    async def _suggest_interest_expansions(
        self, current: List[Dict], analysis: List[Dict], ad_account_id: str
    ) -> List[Dict]:
        """Suggest new interests to add"""
        # Simplified
        return [{
            "suggested_interest": "Related Interest 1",
            "estimated_reach": 300000,
            "rationale": "High affinity with current interests"
        }]
    
    def _recommend_interest_pruning(self, analysis: List[Dict], overlaps: List[Dict]) -> List[Dict]:
        """Recommend interests to remove"""
        return []
    
    def _generate_interest_recommendations(
        self, analysis: List[Dict], expansions: List[Dict], pruning: List[Dict]
    ) -> List[Dict]:
        """Generate interest optimization recommendations"""
        recommendations = []
        
        if expansions:
            recommendations.append({
                "priority": "medium",
                "action": "Test new interest expansions",
                "interests": [e["suggested_interest"] for e in expansions[:3]]
            })
        
        return recommendations
    
    def _calculate_lal_quality_score(self, lal_perf: Dict, source_perf: Dict) -> float:
        """Calculate lookalike quality score"""
        if not source_perf:
            return 0.75  # Default
        
        lal_roas = float(lal_perf.get("roas", 0))
        source_roas = float(source_perf.get("roas", 1))
        
        quality = lal_roas / source_roas if source_roas > 0 else 0.5
        return round(min(1.0, quality), 2)
    
    def _calculate_similarity_score(self, lal_perf: Dict, source_perf: Dict) -> float:
        """Calculate similarity to source audience"""
        return 0.85  # Simplified
    
    def _determine_optimal_lal_percentage(self, metrics: Dict, current: int) -> Dict:
        """Determine optimal LAL percentage"""
        quality = metrics["quality_score"]
        
        if quality > 0.8:
            recommended = min(10, current + 1)
            rationale = "High quality - can expand"
        elif quality < 0.6:
            recommended = max(1, current - 1)
            rationale = "Lower quality - tighten targeting"
        else:
            recommended = current
            rationale = "Current percentage is optimal"
        
        return {
            "current_percentage": current,
            "recommended_percentage": recommended,
            "rationale": rationale
        }
    
    async def _analyze_seed_quality(self, source_id: Optional[str], perf: Dict) -> Dict:
        """Analyze seed audience quality"""
        return {
            "seed_size": 10000,
            "seed_quality": "high",
            "recommendations": "Seed audience is high quality"
        }
    
    def _generate_lal_expansion_recommendations(
        self, metrics: Dict, optimal: Dict, seed: Dict
    ) -> List[Dict]:
        """Generate LAL expansion recommendations"""
        return [{
            "expansion_type": "increase_percentage",
            "from_percentage": optimal["current_percentage"],
            "to_percentage": optimal["recommended_percentage"],
            "expected_reach_increase": f"{(optimal['recommended_percentage'] - optimal['current_percentage']) * 10}%"
        }]
    
    def _generate_lookalike_recommendations(
        self, metrics: Dict, optimal: Dict, seed: Dict, expansions: List[Dict]
    ) -> List[Dict]:
        """Generate lookalike recommendations"""
        recommendations = []
        
        if optimal["recommended_percentage"] != optimal["current_percentage"]:
            recommendations.append({
                "priority": "medium",
                "action": f"Adjust LAL to {optimal['recommended_percentage']}%",
                "rationale": optimal["rationale"]
            })
        
        return recommendations
    
    async def _calculate_audience_overlap(
        self, audience1: Dict, audience2: Dict, ad_account_id: str
    ) -> Dict:
        """Calculate overlap between two audiences"""
        # Simplified - would use Audience Overlap API
        return {
            "overlap_percentage": 35.0,
            "overlap_size": 50000
        }
    
    def _assess_cannibalization_risk(self, overlap: Dict) -> str:
        """Assess cannibalization risk level"""
        overlap_pct = overlap["overlap_percentage"]
        
        if overlap_pct > 70:
            return "critical"
        elif overlap_pct > 50:
            return "high"
        elif overlap_pct > 30:
            return "moderate"
        else:
            return "low"
    
    def _identify_consolidation_opportunities(self, overlaps: List[Dict]) -> List[Dict]:
        """Identify consolidation opportunities"""
        high_overlaps = [o for o in overlaps if o["overlap_percentage"] > 60]
        
        return [{
            "adsets_to_consolidate": [o["adset1_id"], o["adset2_id"]],
            "overlap_percentage": o["overlap_percentage"],
            "rationale": "High audience overlap suggests consolidation"
        } for o in high_overlaps[:3]]
    
    def _generate_exclusion_recommendations(
        self, overlaps: List[Dict], consolidations: List[Dict]
    ) -> List[Dict]:
        """Generate exclusion recommendations"""
        return [{
            "adset_id": overlap["adset1_id"],
            "exclude_audience": overlap["adset2_id"],
            "reason": "Reduce audience duplication"
        } for overlap in overlaps[:3]]
    
    def _generate_overlap_recommendations(
        self, overlaps: List[Dict], consolidations: List[Dict], exclusions: List[Dict]
    ) -> List[Dict]:
        """Generate overlap-based recommendations"""
        recommendations = []
        
        if consolidations:
            recommendations.append({
                "priority": "high",
                "action": f"Consolidate {len(consolidations)} ad set pairs with high overlap",
                "expected_improvement": "20-30% efficiency gain"
            })
        
        return recommendations
    
    def _calculate_days_since_update(self, time_updated: Optional[str]) -> int:
        """Calculate days since last update"""
        if not time_updated:
            return 999
        
        try:
            updated = datetime.fromisoformat(time_updated.replace("Z", "+00:00"))
            days = (datetime.utcnow() - updated).days
            return days
        except (TypeError, ValueError):
            return 999
    
    def _estimate_match_rate(self, audience_info: Dict) -> float:
        """Estimate match rate for custom audience"""
        # Simplified - actual match rate would come from API
        return 0.65
    
    def _calculate_audience_health_score(self, audience_info: Dict) -> float:
        """Calculate overall health score"""
        match_rate = self._estimate_match_rate(audience_info)
        days_since_update = self._calculate_days_since_update(audience_info.get("time_updated"))
        
        freshness_score = max(0, 1 - (days_since_update / 90))  # Degrade over 90 days
        
        health = (match_rate * 0.6 + freshness_score * 0.4)
        return round(health, 2)
    
    def _determine_health_status(self, audience_info: Dict) -> str:
        """Determine health status"""
        score = self._calculate_audience_health_score(audience_info)
        
        if score >= 0.8:
            return "excellent"
        elif score >= 0.6:
            return "good"
        elif score >= 0.4:
            return "fair"
        else:
            return "poor"
    
    async def _analyze_audience_size_trends(self, audience_id: str, days: int) -> Dict:
        """Analyze audience size trends"""
        # Simplified
        return {
            "trend": "growing",
            "growth_rate": 2.5,
            "volatility": 0.15
        }
    
    def _calculate_optimal_refresh_frequency(self, metrics: Dict, trends: Dict) -> str:
        """Calculate optimal refresh frequency"""
        if trends["trend"] == "growing":
            return "every 7 days"
        else:
            return "every 14 days"
    
    def _calculate_next_refresh_date(self, metrics: Dict) -> str:
        """Calculate next recommended refresh date"""
        return (datetime.utcnow() + timedelta(days=7)).strftime("%Y-%m-%d")
    
    def _calculate_freshness_score(self, days_old: int) -> float:
        """Calculate freshness score"""
        return max(0, 1 - (days_old / 90))
    
    def _generate_audience_health_recommendations(
        self, metrics: Dict, trends: Dict, refresh: Dict, quality: Dict
    ) -> List[Dict]:
        """Generate audience health recommendations"""
        recommendations = []
        
        if metrics["health_status"] in ["fair", "poor"]:
            recommendations.append({
                "priority": "high",
                "action": "Refresh custom audience immediately",
                "rationale": f"Health status: {metrics['health_status']}"
            })
        
        if metrics["days_since_update"] > 30:
            recommendations.append({
                "priority": "medium",
                "action": f"Implement {refresh['optimal_refresh_frequency']} refresh schedule",
                "rationale": "Audience data is stale"
            })
        
        return recommendations
    
    def _determine_location_tier(self, location: Dict) -> str:
        """Determine performance tier for location"""
        roas = float(location.get("roas", 0))
        
        if roas >= 3.0:
            return "tier_1"
        elif roas >= 2.0:
            return "tier_2"
        elif roas >= 1.0:
            return "tier_3"
        else:
            return "underperforming"
    
    def _estimate_market_potential(self, location: Dict) -> str:
        """Estimate market potential"""
        # Simplified
        return "medium"
    
    def _calculate_expansion_priority(self, location: Dict) -> int:
        """Calculate expansion priority score"""
        roas = float(location.get("roas", 0))
        conversions = int(location.get("conversions", 0))
        
        return int(roas * conversions / 10)
    
    def _generate_geographic_expansion_recommendations(
        self, all_locations: List[Dict], top: List[Dict], opportunities: List[Dict]
    ) -> Dict:
        """Generate geographic expansion recommendations"""
        return {
            "immediate_expansions": [loc["country"] for loc in opportunities[:3]],
            "scale_existing": [loc["country"] for loc in top[:2]],
            "expected_impact": "30-50% reach increase"
        }
    
    def _generate_location_recommendations(
        self, all_locations: List[Dict], top: List[Dict], opportunities: List[Dict], geo_recs: Dict
    ) -> List[Dict]:
        """Generate location optimization recommendations"""
        recommendations = []
        
        if opportunities:
            recommendations.append({
                "priority": "medium",
                "action": "Expand to new geographic markets",
                "markets": geo_recs["immediate_expansions"]
            })
        
        if top:
            recommendations.append({
                "priority": "high",
                "action": "Increase budget in top-performing markets",
                "markets": geo_recs["scale_existing"]
            })
        
        return recommendations
    
    def _calculate_behavior_effectiveness(self, behavior: Dict, overall: Dict) -> float:
        """Calculate behavior effectiveness score"""
        return 0.75  # Simplified
    
    async def _estimate_behavior_audience_impact(self, behavior: Dict, ad_account_id: str) -> str:
        """Estimate audience size impact"""
        return "medium"  # Simplified
    
    def _analyze_purchase_behaviors(self, behaviors: List[Dict], performance: Dict) -> Dict:
        """Analyze purchase behavior patterns"""
        return {
            "high_intent_behaviors": ["engaged_shoppers", "frequent_buyers"],
            "effectiveness": "high"
        }
    
    async def _suggest_behavior_combinations(
        self, current: List[Dict], analysis: List[Dict], ad_account_id: str
    ) -> List[Dict]:
        """Suggest behavior combinations"""
        return [{
            "combination": ["engaged_shoppers", "mobile_device_users"],
            "estimated_performance_lift": "15-25%",
            "rationale": "High affinity combination"
        }]
    
    def _generate_behavior_recommendations(
        self, analysis: List[Dict], purchase: Dict, combinations: List[Dict]
    ) -> List[Dict]:
        """Generate behavior targeting recommendations"""
        recommendations = []
        
        if combinations:
            recommendations.append({
                "priority": "medium",
                "action": "Test behavior combinations",
                "combinations": [c["combination"] for c in combinations]
            })
        
        return recommendations


# Singleton instance
_engine_instance = None


def get_audience_intelligence_engine() -> AudienceIntelligenceEngine:
    """Get or create the audience intelligence engine instance"""
    global _engine_instance
    if _engine_instance is None:
        from .meta_client import get_client
        _engine_instance = AudienceIntelligenceEngine(get_client())
    return _engine_instance

