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 detect_performance_degradation_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.detect_performance_degradation(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_detect_performance_degradation_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def analyze_conversion_funnel_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.analyze_conversion_funnel(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_analyze_conversion_funnel_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def score_audience_quality_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.score_audience_quality(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_score_audience_quality_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def analyze_creative_fatigue_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.analyze_creative_fatigue(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_analyze_creative_fatigue_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def audit_bidding_efficiency_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.audit_bidding_efficiency(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_audit_bidding_efficiency_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def diagnose_learning_phase_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.diagnose_learning_phase(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_diagnose_learning_phase_failed", error=str(exc))
        return ToolResult(ok=False, error={"message": str(exc)})

async def detect_campaign_interference_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    try:
        from ..performance_diagnostics import PerformanceDiagnosticsEngine
        engine = PerformanceDiagnosticsEngine(client)
        return await engine.detect_campaign_interference(arguments) # type: ignore
    except Exception as exc:
        logger.error("tool_detect_campaign_interference_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.diagnostics.detect_degradation": (
            mcp_types.Tool(
                name="meta.diagnostics.detect_degradation",
                description="Detect performance degradation using statistical anomaly detection. Identifies drops in ROAS, CTR, or conversion rates. Use for troubleshooting underperforming campaigns.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "entity_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "entity_id"],
                },
            ),
            partial(detect_performance_degradation_handler, client),
        ),
        "meta.diagnostics.analyze_funnel": (
            mcp_types.Tool(
                name="meta.diagnostics.analyze_funnel",
                description="Analyze conversion funnel bottlenecks. Identify where users drop off between click, landing, and purchase. Use for diagnosing conversion issues.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(analyze_conversion_funnel_handler, client),
        ),
        "meta.diagnostics.score_audience": (
            mcp_types.Tool(
                name="meta.diagnostics.score_audience",
                description="Score audience quality based on conversion rates, LTV, and engagement. Grades audiences A-F for performance prediction. Use for audience health assessment.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "audience_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "audience_id"],
                },
            ),
            partial(score_audience_quality_handler, client),
        ),
        "meta.diagnostics.analyze_fatigue": (
            mcp_types.Tool(
                name="meta.diagnostics.analyze_fatigue",
                description="Analyze creative fatigue by tracking frequency vs. CTR decay. Predicts creative wear-out timing and recommends refresh. Use for creative lifecycle management.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "ad_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "ad_id"],
                },
            ),
            partial(analyze_creative_fatigue_handler, client),
        ),
        "meta.diagnostics.audit_bidding": (
            mcp_types.Tool(
                name="meta.diagnostics.audit_bidding",
                description="Audit bidding efficiency by comparing actual vs. target CPA and ROAS. Identifies bid strategy misconfigurations. Use for bid troubleshooting.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(audit_bidding_efficiency_handler, client),
        ),
        "meta.diagnostics.diagnose_learning": (
            mcp_types.Tool(
                name="meta.diagnostics.diagnose_learning",
                description="Diagnose learning phase issues for ad sets. Identifies exit timing, volatility causes, and optimization recommendations. Use for new campaign troubleshooting.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                        "ad_set_id": {"type": "string"},
                    },
                    "required": ["ad_account_id", "ad_set_id"],
                },
            ),
            partial(diagnose_learning_phase_handler, client),
        ),
        "meta.diagnostics.detect_interference": (
            mcp_types.Tool(
                name="meta.diagnostics.detect_interference",
                description="Detect campaign interference and audience overlap. Identifies cannibalizing campaigns bidding against each other. Use for account structure optimization.",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "ad_account_id": {"type": "string"},
                    },
                    "required": ["ad_account_id"],
                },
            ),
            partial(detect_campaign_interference_handler, client),
        ),
    }
