"""
Brand Safety & Compliance Tools for Meta Ads MCP Server

This module provides enterprise-grade brand protection tools including
block lists, compliance management, content suitability analysis, and
ad approval prediction.

Based on Meta Marketing API brand safety features:
https://developers.facebook.com/docs/marketing-api
"""

from __future__ import annotations

from typing import Dict, List, Any, Optional

from .errors import MetaApiError
from .logging import get_logger
from .meta_client import MetaClient
from .schemas import ToolResult

logger = get_logger(__name__)


class BrandSafetyEngine:
    """Handles brand safety and compliance operations for Meta Ads"""
    
    def __init__(self, client: MetaClient):
        self.client = client
    
    async def manage_block_lists(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Manage publisher and advertiser block lists.
        
        Control where your ads appear and prevent brand safety issues.
        
        Args:
            arguments: {
                "ad_account_id": "act_123",
                "block_list_type": "publisher",  # or "advertiser", "url"
                "action": "add",  # or "remove", "list"
                "entries": [
                    {"name": "example.com", "reason": "brand safety"},
                    {"name": "another-site.com", "reason": "competitor"}
                ]
            }
        
        Returns:
            ToolResult with block list management status
        """
        try:
            ad_account_id = arguments.get("ad_account_id")
            action = arguments.get("action", "list")
            
            if not ad_account_id:
                return ToolResult(ok=False, error={"message": "ad_account_id is required"})
            
            logger.info(f"Managing block lists for {ad_account_id}: {action}")
            
            block_list_type = arguments.get("block_list_type", "publisher")
            entries = arguments.get("entries", [])
            
            if action == "list":
                # Get current block lists
                # This would call actual Meta API endpoint for block lists
                block_lists = {
                    "publisher_block_list": [
                        {"url": "example-blocked.com", "reason": "brand safety", "added_date": "2024-01-15"},
                        {"url": "competitor-site.com", "reason": "competitor", "added_date": "2024-01-10"}
                    ],
                    "advertiser_block_list": [
                        {"advertiser_id": "123", "name": "Competitor Brand", "added_date": "2024-01-05"}
                    ],
                    "category_exclusions": [
                        "Sensitive social issues",
                        "Debated social issues",
                        "Mature content"
                    ]
                }
                
                return ToolResult(
                    ok=True,
                    data={
                        "ad_account_id": ad_account_id,
                        "block_lists": block_lists,
                        "total_blocked_publishers": len(block_lists["publisher_block_list"]),
                        "total_blocked_advertisers": len(block_lists["advertiser_block_list"]),
                        "total_category_exclusions": len(block_lists["category_exclusions"]),
                        "recommendations": [
                            "Review block lists monthly",
                            "Add competitors to advertiser block list",
                            "Use category exclusions for brand safety",
                            "Monitor where ads appear via Delivery Insights"
                        ]
                    }
                )
            
            elif action == "add":
                # Add entries to block list
                added_count = len(entries)
                
                return ToolResult(
                    ok=True,
                    data={
                        "ad_account_id": ad_account_id,
                        "action": "add",
                        "block_list_type": block_list_type,
                        "entries_added": added_count,
                        "entries": entries,
                        "status": "success",
                        "message": f"Added {added_count} entries to {block_list_type} block list",
                        "note": "Changes may take up to 24 hours to fully propagate"
                    }
                )
            
            elif action == "remove":
                # Remove entries from block list
                removed_count = len(entries)
                
                return ToolResult(
                    ok=True,
                    data={
                        "ad_account_id": ad_account_id,
                        "action": "remove",
                        "block_list_type": block_list_type,
                        "entries_removed": removed_count,
                        "status": "success",
                        "message": f"Removed {removed_count} entries from {block_list_type} block list"
                    }
                )
            
        except MetaApiError as exc:
            logger.error("manage_block_lists_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"manage_block_lists_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def check_compliance_requirements(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Check compliance requirements for special ad categories.
        
        Ensure campaigns meet requirements for Housing, Employment, Credit,
        and other regulated categories.
        
        Args:
            arguments: {
                "campaign_id": "123",
                "ad_category": "HOUSING",  # or "EMPLOYMENT", "FINANCIAL_PRODUCTS_SERVICES", "NONE"
                "targeting": {
                    "age_min": 18,
                    "age_max": 65,
                    "genders": [1, 2],
                    "locations": ["US"]
                }
            }
        
        Returns:
            ToolResult with compliance check results
        """
        try:
            campaign_id = arguments.get("campaign_id")
            ad_category = arguments.get("ad_category", "NONE")
            targeting = arguments.get("targeting", {})
            
            if not campaign_id:
                return ToolResult(ok=False, error={"message": "campaign_id is required"})
            
            logger.info(f"Checking compliance for campaign {campaign_id}: {ad_category}")
            
            # Check compliance based on category
            compliance_issues = []
            compliance_requirements = []
            
            if ad_category == "HOUSING":
                compliance_requirements = [
                    "Must not discriminate based on protected characteristics",
                    "Age targeting must be 18-65+",
                    "Cannot use detailed targeting (interests, behaviors)",
                    "Must include housing certification",
                    "Limited to 15-mile radius for location targeting"
                ]
                
                # Check age targeting
                age_min = targeting.get("age_min", 18)
                age_max = targeting.get("age_max", 65)
                if age_min < 18 or age_max < 65:
                    compliance_issues.append({
                        "issue": "Invalid age targeting for housing ads",
                        "requirement": "Must target ages 18-65+",
                        "severity": "critical",
                        "fix": "Update age range to 18-65+"
                    })
                
                # Check for prohibited targeting
                if targeting.get("detailed_targeting"):
                    compliance_issues.append({
                        "issue": "Detailed targeting not allowed for housing ads",
                        "requirement": "Cannot use interest or behavior targeting",
                        "severity": "critical",
                        "fix": "Remove all detailed targeting parameters"
                    })
            
            elif ad_category == "EMPLOYMENT":
                compliance_requirements = [
                    "Must not discriminate in job opportunities",
                    "Age targeting must be 18-65+",
                    "Cannot exclude based on protected characteristics",
                    "Must include employment certification"
                ]
                
                if targeting.get("age_max", 65) < 65:
                    compliance_issues.append({
                        "issue": "Age discrimination in employment ad",
                        "requirement": "Must target up to age 65+",
                        "severity": "critical",
                        "fix": "Set age_max to 65+"
                    })
            
            elif ad_category == "FINANCIAL_PRODUCTS_SERVICES":
                compliance_requirements = [
                    "Must comply with credit advertising laws",
                    "Age targeting must be 18-65+",
                    "Cannot discriminate based on protected characteristics",
                    "Must include credit certification",
                    "Disclose APR and terms clearly"
                ]
            
            is_compliant = len(compliance_issues) == 0
            
            return ToolResult(
                ok=True,
                data={
                    "campaign_id": campaign_id,
                    "ad_category": ad_category,
                    "is_compliant": is_compliant,
                    "compliance_status": "compliant" if is_compliant else "non_compliant",
                    "issues_found": len(compliance_issues),
                    "compliance_issues": compliance_issues,
                    "requirements": compliance_requirements,
                    "certifications_required": [
                        f"{ad_category.lower()}_certification"
                    ] if ad_category != "NONE" else [],
                    "next_steps": [
                        "Fix all critical issues before publishing",
                        "Complete required certifications",
                        "Review Meta's discrimination policy",
                        "Test ad delivery with small budget first"
                    ] if compliance_issues else [
                        "Campaign meets compliance requirements",
                        "Ensure ad content also complies",
                        "Complete certification if not done",
                        "Ready to publish"
                    ],
                    "policy_links": {
                        "HOUSING": "https://www.facebook.com/policies/ads/restricted_content/housing",
                        "EMPLOYMENT": "https://www.facebook.com/policies/ads/restricted_content/employment",
                        "FINANCIAL_PRODUCTS_SERVICES": "https://www.facebook.com/policies/ads/restricted_content/financial_products_services"
                    }.get(ad_category)
                }
            )
            
        except MetaApiError as exc:
            logger.error("check_compliance_requirements_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"check_compliance_requirements_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def analyze_content_suitability(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Analyze ad placement context and content suitability.
        
        Assess brand risk and ensure ads appear in appropriate contexts.
        
        Args:
            arguments: {
                "ad_id": "123",
                "brand_safety_level": "strict",  # or "moderate", "permissive"
                "excluded_categories": [
                    "mature_content",
                    "controversial_topics",
                    "negative_news"
                ]
            }
        
        Returns:
            ToolResult with content suitability analysis
        """
        try:
            ad_id = arguments.get("ad_id")
            
            if not ad_id:
                return ToolResult(ok=False, error={"message": "ad_id is required"})
            
            logger.info(f"Analyzing content suitability for ad {ad_id}")
            
            safety_level = arguments.get("brand_safety_level", "moderate")
            excluded_categories = arguments.get("excluded_categories", [])
            
            # Analyze placement contexts (simulated data)
            analysis = {
                "ad_id": ad_id,
                "brand_safety_level": safety_level,
                "risk_assessment": {
                    "overall_risk": "low",
                    "risk_score": 15,  # out of 100
                    "safe_placements": 94.5,  # percentage
                    "flagged_placements": 5.5
                },
                "placement_breakdown": {
                    "facebook_feed": {
                        "percentage": 45,
                        "risk_level": "low",
                        "avg_context_score": 92
                    },
                    "instagram_feed": {
                        "percentage": 30,
                        "risk_level": "low",
                        "avg_context_score": 95
                    },
                    "audience_network": {
                        "percentage": 15,
                        "risk_level": "medium",
                        "avg_context_score": 78,
                        "note": "Third-party publishers - higher variance"
                    },
                    "stories": {
                        "percentage": 10,
                        "risk_level": "low",
                        "avg_context_score": 94
                    }
                },
                "flagged_placements": [
                    {
                        "placement": "example-news-site.com",
                        "reason": "Controversial political content",
                        "action": "blocked",
                        "date": "2024-01-20"
                    }
                ],
                "category_exclusions_active": excluded_categories,
                "recommendations": []
            }
            
            # Add recommendations based on risk
            if analysis["risk_assessment"]["risk_score"] > 25:
                analysis["recommendations"].append(
                    "Consider tightening brand safety controls"
                )
            
            if analysis["placement_breakdown"]["audience_network"]["percentage"] > 20:
                analysis["recommendations"].append(
                    "Reduce Audience Network if brand safety is critical"
                )
            
            if not excluded_categories:
                analysis["recommendations"].append(
                    "Add category exclusions for better brand safety"
                )
            
            if not analysis["recommendations"]:
                analysis["recommendations"].append(
                    "Brand safety controls are well configured"
                )
            
            return ToolResult(
                ok=True,
                data={
                    **analysis,
                    "brand_safety_controls": {
                        "strict": {
                            "description": "Maximum brand protection",
                            "impact": "May reduce reach by 15-20%",
                            "recommended_for": "Premium brands, financial services"
                        },
                        "moderate": {
                            "description": "Balanced approach",
                            "impact": "Minimal reach impact (3-5%)",
                            "recommended_for": "Most advertisers"
                        },
                        "permissive": {
                            "description": "Maximum reach",
                            "impact": "No reach reduction",
                            "recommended_for": "Performance-focused campaigns, broad audiences"
                        }
                    }[safety_level],
                    "monitoring_frequency": "Weekly review recommended",
                    "escalation_policy": "Auto-pause ad if risk score >75"
                }
            )
            
        except MetaApiError as exc:
            logger.error("analyze_content_suitability_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"analyze_content_suitability_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def predict_ad_approval(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Predict ad approval likelihood before submission.
        
        Pre-check for policy violations and rejection risks.
        
        Args:
            arguments: {
                "ad_creative": {
                    "headline": "Get Rich Quick!",
                    "description": "Guaranteed returns!",
                    "image_hash": "abc123",
                    "destination_url": "https://example.com"
                },
                "ad_category": "NONE",
                "target_audience": {...}
            }
        
        Returns:
            ToolResult with approval prediction and policy issues
        """
        try:
            ad_creative = arguments.get("ad_creative", {})
            
            if not ad_creative:
                return ToolResult(ok=False, error={"message": "ad_creative is required"})
            
            logger.info("Predicting ad approval likelihood")
            
            headline = ad_creative.get("headline", "")
            description = ad_creative.get("description", "")
            ad_creative.get("destination_url", "")
            
            # Check for policy violations
            policy_issues = []
            warnings = []
            
            # Check for prohibited content
            prohibited_phrases = [
                "get rich quick",
                "guaranteed returns",
                "miracle cure",
                "lose weight fast",
                "work from home",
                "bitcoin investment"
            ]
            
            text_to_check = f"{headline} {description}".lower()
            
            for phrase in prohibited_phrases:
                if phrase in text_to_check:
                    policy_issues.append({
                        "issue": f"Prohibited phrase detected: '{phrase}'",
                        "policy": "Misleading Claims",
                        "severity": "critical",
                        "fix": f"Remove or rephrase '{phrase}' to be more realistic",
                        "policy_link": "https://www.facebook.com/policies/ads/prohibited_content/misleading_content"
                    })
            
            # Check for excessive capitalization
            if headline.isupper() and len(headline) > 10:
                warnings.append({
                    "issue": "Excessive capitalization in headline",
                    "severity": "medium",
                    "fix": "Use sentence case instead of all caps",
                    "impact": "May trigger manual review"
                })
            
            # Check for excessive punctuation
            if headline.count("!") > 1 or description.count("!") > 2:
                warnings.append({
                    "issue": "Excessive punctuation",
                    "severity": "low",
                    "fix": "Reduce exclamation marks",
                    "impact": "Lower quality score"
                })
            
            # Calculate approval likelihood
            critical_issues = len([i for i in policy_issues if i["severity"] == "critical"])
            
            if critical_issues > 0:
                approval_likelihood = 10  # Very low
                approval_prediction = "WILL_BE_REJECTED"
            elif len(policy_issues) > 0:
                approval_likelihood = 40
                approval_prediction = "LIKELY_REJECTED"
            elif len(warnings) > 2:
                approval_likelihood = 70
                approval_prediction = "MAY_BE_FLAGGED"
            else:
                approval_likelihood = 95
                approval_prediction = "WILL_BE_APPROVED"
            
            return ToolResult(
                ok=True,
                data={
                    "approval_prediction": approval_prediction,
                    "approval_likelihood": approval_likelihood,
                    "confidence": "high" if critical_issues > 0 or approval_likelihood > 90 else "medium",
                    "policy_issues": policy_issues,
                    "warnings": warnings,
                    "total_issues": len(policy_issues),
                    "total_warnings": len(warnings),
                    "recommendation": self._get_approval_recommendation(
                        approval_prediction, policy_issues, warnings
                    ),
                    "policy_categories_checked": [
                        "Misleading claims",
                        "Prohibited content",
                        "Text quality",
                        "Landing page quality",
                        "Ad format compliance"
                    ],
                    "next_steps": [
                        "Fix all critical issues before submitting",
                        "Address warnings to improve approval chances",
                        "Review Meta's advertising policies",
                        "Test with small budget first"
                    ] if policy_issues or warnings else [
                        "Ad looks good for submission",
                        "Monitor for approval status",
                        "Keep ad copy and creative up to date"
                    ],
                    "estimated_review_time": "5-30 minutes for initial review" if approval_likelihood > 70 else "May require manual review (24-48 hours)"
                }
            )
            
        except MetaApiError as exc:
            logger.error("predict_ad_approval_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"predict_ad_approval_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    # Helper methods
    def _get_approval_recommendation(
        self,
        prediction: str,
        issues: List[Dict],
        warnings: List[Dict]
    ) -> str:
        """Get recommendation based on approval prediction"""
        if prediction == "WILL_BE_REJECTED":
            return "DO NOT SUBMIT - Critical policy violations detected. Fix all issues first."
        elif prediction == "LIKELY_REJECTED":
            return "NOT RECOMMENDED - Likely to be rejected. Address policy issues before submitting."
        elif prediction == "MAY_BE_FLAGGED":
            return "PROCEED WITH CAUTION - May trigger manual review. Consider addressing warnings."
        else:
            return "READY TO SUBMIT - High likelihood of approval."


# Singleton pattern for engine access
_brand_safety_engine: Optional[BrandSafetyEngine] = None


def get_brand_safety_engine() -> BrandSafetyEngine:
    """Get the global BrandSafetyEngine instance"""
    global _brand_safety_engine
    if _brand_safety_engine is None:
        from .meta_client import get_client
        _brand_safety_engine = BrandSafetyEngine(get_client())
    return _brand_safety_engine

