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

from mcp import types as mcp_types

from ..logging import get_logger
from ..meta_client import MetaClient
from ..schemas import ToolResult
from .base import ToolHandler

logger = get_logger(__name__)

async def get_hourly_performance_snapshot_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.get_hourly_performance_snapshot(**arguments) # method uses individual args, unwrap
    except Exception as exc:
        logger.error("tool_get_hourly_performance_snapshot_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def check_campaign_health_instant_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.check_campaign_health_instant(**arguments)
    except Exception as exc:
        logger.error("tool_check_campaign_health_instant_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def detect_performance_deterioration_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.detect_performance_deterioration(**arguments)
    except Exception as exc:
        logger.error("tool_detect_performance_deterioration_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def recommend_top_5_actions_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.recommend_top_5_actions(**arguments)
    except Exception as exc:
        logger.error("tool_recommend_top_5_actions_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def monitor_budget_burn_rate_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.monitor_budget_burn_rate(**arguments)
    except Exception as exc:
        logger.error("tool_monitor_budget_burn_rate_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def check_auction_competition_now_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.check_auction_competition_now(**arguments)
    except Exception as exc:
        logger.error("tool_check_auction_competition_now_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def detect_creative_fatigue_radar_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.detect_creative_fatigue_radar(**arguments)
    except Exception as exc:
        logger.error("tool_detect_creative_fatigue_radar_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def track_conversion_rate_realtime_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..tactical_operations import TacticalOperationsEngine
        engine = TacticalOperationsEngine(client)
        return await engine.track_conversion_rate_realtime(**arguments)
    except Exception as exc:
        logger.error("tool_track_conversion_rate_realtime_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.tactical.performance_snapshot": (
            mcp_types.Tool(
                name="meta.tactical.performance_snapshot",
                description="Get hourly real-time performance snapshot. View current spend, CPA, ROAS, and delivery status for immediate campaign monitoring and intraday optimization decisions.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "entity_type": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(get_hourly_performance_snapshot_handler, client),
        ),
        "meta.tactical.check_health": (
            mcp_types.Tool(
                name="meta.tactical.check_health",
                description="Instant campaign health check. Diagnose delivery issues, learning phase status, budget utilization, and quality warnings. Use for troubleshooting underperforming campaigns.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "entity_type": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(check_campaign_health_instant_handler, client),
        ),
        "meta.tactical.detect_deterioration": (
            mcp_types.Tool(
                name="meta.tactical.detect_deterioration",
                description="Detect performance deterioration. Identify declining metrics, trend reversals, and early warning signs of campaign problems. Alert on CPA spikes and ROAS drops.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "entity_type": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(detect_performance_deterioration_handler, client),
        ),
        "meta.tactical.recommend_actions": (
            mcp_types.Tool(
                name="meta.tactical.recommend_actions",
                description="Get top 5 recommended optimization actions. Prioritized suggestions ranked by impact for budget reallocation, bid adjustments, and audience refinement.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "entity_type": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(recommend_top_5_actions_handler, client),
        ),
        "meta.tactical.monitor_burn_rate": (
            mcp_types.Tool(
                name="meta.tactical.monitor_burn_rate",
                description="Monitor budget burn rate and pacing. Track daily spend velocity, forecast budget exhaustion, and detect overspend or underspend patterns.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(monitor_budget_burn_rate_handler, client),
        ),
        "meta.tactical.check_competition": (
            mcp_types.Tool(
                name="meta.tactical.check_competition",
                description="Check current auction competition and bid landscape. View CPM trends, impression share, and competitor activity in your target audience.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(check_auction_competition_now_handler, client),
        ),
        "meta.tactical.detect_fatigue_radar": (
            mcp_types.Tool(
                name="meta.tactical.detect_fatigue_radar",
                description="Detect creative fatigue signals. Monitor frequency, CTR decline, and audience saturation. Recommends creative refresh timing and rotation strategy.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "entity_type": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(detect_creative_fatigue_radar_handler, client),
        ),
        "meta.tactical.track_conversion_rate": (
            mcp_types.Tool(
                name="meta.tactical.track_conversion_rate",
                description="Track conversion rate in real-time. Monitor purchase, lead, and custom event rates with hourly granularity for immediate funnel optimization.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                        "conversion_event": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(track_conversion_rate_realtime_handler, client),
        ),
    }
