from typing import Any, Dict, Tuple
from functools import partial
from datetime import datetime, timedelta

from mcp import types as mcp_types

from ..logging import get_logger
from ..meta_client import MetaClient
from ..schemas import (
    BehaviorTargetingOptimizerRequest,
    CustomAudienceHealthMonitorRequest,
    DemographicPerformanceProfilerRequest,
    InterestTargetingAnalyzerRequest,
    LookalikePerformanceEvaluatorRequest,
    ToolResult,
)
from .base import ToolHandler

logger = get_logger(__name__)


def _default_time_range(days: int = 30) -> Dict[str, str]:
    today = datetime.utcnow().date()
    since = today - timedelta(days=days)
    return {"since": since.isoformat(), "until": today.isoformat()}


def _to_payload(data: Any) -> Any:
    if hasattr(data, "model_dump"):
        return data.model_dump(mode="json")
    return data


async def demographic_performance_profiler_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..targeting_intelligence import TargetingIntelligenceEngine
        engine = TargetingIntelligenceEngine(client)
        payload = dict(arguments)
        payload.setdefault("time_range", _default_time_range())
        request = DemographicPerformanceProfilerRequest.model_validate(payload)
        data = await engine.demographic_performance_profiler(request)
        return ToolResult(ok=True, data=_to_payload(data))
    except Exception as exc:
        logger.error("tool_demographic_performance_profiler_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def interest_targeting_analyzer_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..targeting_intelligence import TargetingIntelligenceEngine
        engine = TargetingIntelligenceEngine(client)
        request = InterestTargetingAnalyzerRequest.model_validate(arguments)
        data = await engine.interest_targeting_analyzer(request)
        return ToolResult(ok=True, data=_to_payload(data))
    except Exception as exc:
        logger.error("tool_interest_targeting_analyzer_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def behavior_targeting_optimizer_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..targeting_intelligence import TargetingIntelligenceEngine
        engine = TargetingIntelligenceEngine(client)
        request = BehaviorTargetingOptimizerRequest.model_validate(arguments)
        data = await engine.behavior_targeting_optimizer(request)
        return ToolResult(ok=True, data=_to_payload(data))
    except Exception as exc:
        logger.error("tool_behavior_targeting_optimizer_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def custom_audience_health_monitor_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..targeting_intelligence import TargetingIntelligenceEngine
        engine = TargetingIntelligenceEngine(client)
        request = CustomAudienceHealthMonitorRequest.model_validate(arguments)
        data = await engine.custom_audience_health_monitor(request)
        return ToolResult(ok=True, data=_to_payload(data))
    except Exception as exc:
        logger.error("tool_custom_audience_health_monitor_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def lookalike_performance_evaluator_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..targeting_intelligence import TargetingIntelligenceEngine
        engine = TargetingIntelligenceEngine(client)
        request = LookalikePerformanceEvaluatorRequest.model_validate(arguments)
        data = await engine.lookalike_performance_evaluator(request)
        return ToolResult(ok=True, data=_to_payload(data))
    except Exception as exc:
        logger.error("tool_lookalike_performance_evaluator_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

def get_tools(client: MetaClient) -> Dict[str, Tuple[mcp_types.Tool, ToolHandler]]:
    return {
        "meta.targeting.profile_demographics": (
            mcp_types.Tool(
                name="meta.targeting.profile_demographics",
                description="Profile demographic performance across age, gender, and location. Identify top-converting segments. Use for demographic optimization.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(demographic_performance_profiler_handler, client),
        ),
        "meta.targeting.analyze_interests": (
            mcp_types.Tool(
                name="meta.targeting.analyze_interests",
                description="Analyze interest targeting performance by category. Find high-performing and wasted interests. Use for interest targeting optimization.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "interests": {"type": "array"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(interest_targeting_analyzer_handler, client),
        ),
        "meta.targeting.optimize_behaviors": (
            mcp_types.Tool(
                name="meta.targeting.optimize_behaviors",
                description="Optimize behavior targeting based on purchase, travel, and device behaviors. Improve conversion rates. Use for behavior targeting refinement.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(behavior_targeting_optimizer_handler, client),
        ),
        "meta.targeting.monitor_audience_health": (
            mcp_types.Tool(
                name="meta.targeting.monitor_audience_health",
                description="Monitor custom audience health including size decay, match rates, and freshness. Detect audience degradation. Use for audience maintenance.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "audience_ids": {"type": "array"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(custom_audience_health_monitor_handler, client),
        ),
        "meta.targeting.evaluate_lookalikes": (
            mcp_types.Tool(
                name="meta.targeting.evaluate_lookalikes",
                description="Evaluate lookalike audience performance across different percentage sizes. Compare 1%-10% lookalikes. Use for lookalike optimization.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "lookalike_specs": {"type": "array"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(lookalike_performance_evaluator_handler, client),
        ),
    }
