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

from mcp import types as mcp_types

from ..errors import MetaApiError
from ..logging import get_logger
from ..meta_client import MetaClient
from ..schemas import (
    GetBusinessHierarchyRequest,
    CrossAccountInsightsRequest,
    CrossAccountOperationRequest,
    ValidateAccountAccessRequest,
    ToolResult
)
from .base import ToolHandler, _tool_schema

logger = get_logger(__name__)

async def get_business_hierarchy_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    request = GetBusinessHierarchyRequest.model_validate(arguments)
    try:
        from ..multi_account import MultiAccountManager
        manager = MultiAccountManager(client)
        hierarchy = await manager.get_business_hierarchy(request.business_id)
        
        # Convert to dict for JSON serialization
        hierarchy_dict = {
            "business_id": hierarchy.business_id,
            "business_name": hierarchy.business_name,
            "ad_accounts": [
                {
                    "id": acc.id,
                    "name": acc.name,
                    "account_type": acc.account_type.value,
                    "currency": acc.currency,
                    "timezone": acc.timezone,
                    "is_active": acc.is_active,
                    "metadata": acc.metadata
                }
                for acc in hierarchy.ad_accounts
                if request.include_inactive or acc.is_active
            ],
            "pages": [
                {
                    "id": acc.id,
                    "name": acc.name,
                    "account_type": acc.account_type.value,
                    "metadata": acc.metadata
                }
                for acc in hierarchy.pages
            ],
            "instagram_accounts": [
                {
                    "id": acc.id,
                    "name": acc.name,
                    "account_type": acc.account_type.value,
                    "metadata": acc.metadata
                }
                for acc in hierarchy.instagram_accounts
            ],
            "child_businesses": [
                {
                    "business_id": child.business_id,
                    "business_name": child.business_name,
                    "ad_account_count": len(child.ad_accounts)
                }
                for child in hierarchy.child_businesses
            ]
        }
        
        return ToolResult(ok=True, data=hierarchy_dict)
    except MetaApiError as exc:
        logger.error("tool_get_business_hierarchy_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())

async def cross_account_insights_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    request = CrossAccountInsightsRequest.model_validate(arguments)
    try:
        from ..multi_account import MultiAccountManager
        manager = MultiAccountManager(client)
        results = await manager.cross_account_insights(
            request.account_ids,
            request.fields,
            request.time_range,
            request.level
        )
        return ToolResult(ok=True, data=results)
    except MetaApiError as exc:
        logger.error("tool_cross_account_insights_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())

async def cross_account_operation_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    request = CrossAccountOperationRequest.model_validate(arguments)
    try:
        from ..multi_account import MultiAccountManager
        manager = MultiAccountManager(client)
        results = await manager.cross_account_campaign_management(
            request.account_ids,
            request.operation,
            request.parameters
        )
        return ToolResult(ok=True, data=results)
    except MetaApiError as exc:
        logger.error("tool_cross_account_operation_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())

async def validate_account_access_handler(client: MetaClient, arguments: Dict[str, Any]) -> ToolResult:
    request = ValidateAccountAccessRequest.model_validate(arguments)
    try:
        from ..multi_account import MultiAccountManager
        manager = MultiAccountManager(client)
        results = await manager.validate_account_access(request.account_ids)
        return ToolResult(ok=True, data=results)
    except MetaApiError as exc:
        logger.error("tool_validate_account_access_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())

def get_tools(client: MetaClient) -> Dict[str, Tuple[mcp_types.Tool, ToolHandler]]:
    return {
        "meta.get_business_hierarchy": (
            mcp_types.Tool(
                name="meta.get_business_hierarchy",
                description="Get full hierarchy of Business Manager including ad accounts, pages, and child businesses. Map enterprise structure. Use for portfolio discovery.",
                inputSchema=_tool_schema(GetBusinessHierarchyRequest),
            ),
            partial(get_business_hierarchy_handler, client),
        ),
        "meta.cross_account_insights": (
            mcp_types.Tool(
                name="meta.cross_account_insights",
                description="Get aggregated insights across multiple ad accounts simultaneously. Compare accounts in one call. Use for agency/enterprise reporting.",
                inputSchema=_tool_schema(CrossAccountInsightsRequest),
            ),
            partial(cross_account_insights_handler, client),
        ),
        "meta.cross_account_operation": (
            mcp_types.Tool(
                name="meta.cross_account_operation",
                description="Perform bulk operations across multiple ad accounts at once. Pause, resume, or update many accounts. Use for agency bulk management.",
                inputSchema=_tool_schema(CrossAccountOperationRequest),
            ),
            partial(cross_account_operation_handler, client),
        ),
        "meta.validate_account_access": (
            mcp_types.Tool(
                name="meta.validate_account_access",
                description="Validate access and permissions for multiple ad accounts. Check API access before operations. Use for permission auditing.",
                inputSchema=_tool_schema(ValidateAccountAccessRequest),
            ),
            partial(validate_account_access_handler, client),
        ),
    }
