"""Instant Experience (Canvas) tools for Meta Marketing API.

This module provides tools for managing full-screen mobile experiences
(formerly called Canvas ads).
"""

from __future__ import annotations

from typing import Any, Dict

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

logger = get_logger(__name__)


async def create_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Create a new Instant Experience (Canvas).
    
    Args:
        arguments: {
            "business_id": "123",
            "name": "My Canvas",
            "body_elements": [
                {
                    "element_type": "HEADER",
                    "style": "...",
                    ...
                }
            ]
        }
        
    Returns:
        ToolResult with created canvas ID
    """
    try:
        client = get_client()
        business_id = arguments.get("business_id")
        
        if not business_id:
            return ToolResult(ok=False, error={"message": "business_id is required"})
        
        canvas_data = {
            "name": arguments.get("name"),
            "body_elements": arguments.get("body_elements", []),
        }
        
        # Add optional fields
        if "background_color" in arguments:
            canvas_data["background_color"] = arguments["background_color"]
        if "is_published" in arguments:
            canvas_data["is_published"] = arguments["is_published"]
        
        response = await client.post(
            f"{business_id}/canvas_elements",
            body=canvas_data
        )
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("create_canvas_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def get_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Get details of a specific Instant Experience.
    
    Args:
        arguments: {"canvas_id": "123"}
        
    Returns:
        ToolResult with canvas details
    """
    try:
        client = get_client()
        canvas_id = arguments.get("canvas_id")
        
        if not canvas_id:
            return ToolResult(ok=False, error={"message": "canvas_id is required"})
        
        fields = [
            "id",
            "name",
            "body_elements",
            "background_color",
            "is_published",
            "canvas_link",
            "owner_page",
        ]
        
        response = await client.get(
            canvas_id,
            params={"fields": ",".join(fields)}
        )
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("get_canvas_failed", canvas_id=canvas_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def update_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Update an existing Instant Experience.
    
    Args:
        arguments: {
            "canvas_id": "123",
            "name": "Updated Name",
            "body_elements": [...]
        }
        
    Returns:
        ToolResult with success status
    """
    try:
        client = get_client()
        canvas_id = arguments.get("canvas_id")
        
        if not canvas_id:
            return ToolResult(ok=False, error={"message": "canvas_id is required"})
        
        update_data = {}
        
        if "name" in arguments:
            update_data["name"] = arguments["name"]
        if "body_elements" in arguments:
            update_data["body_elements"] = arguments["body_elements"]
        if "background_color" in arguments:
            update_data["background_color"] = arguments["background_color"]
        if "is_published" in arguments:
            update_data["is_published"] = arguments["is_published"]
        
        response = await client.post(canvas_id, body=update_data)
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("update_canvas_failed", canvas_id=canvas_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def delete_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Delete an Instant Experience.
    
    Args:
        arguments: {"canvas_id": "123"}
        
    Returns:
        ToolResult with success status
    """
    try:
        client = get_client()
        canvas_id = arguments.get("canvas_id")
        
        if not canvas_id:
            return ToolResult(ok=False, error={"message": "canvas_id is required"})
        
        response = await client.delete(canvas_id)
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("delete_canvas_failed", canvas_id=canvas_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def preview_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Get a preview URL for an Instant Experience.
    
    Args:
        arguments: {"canvas_id": "123"}
        
    Returns:
        ToolResult with preview URL
    """
    try:
        client = get_client()
        canvas_id = arguments.get("canvas_id")
        
        if not canvas_id:
            return ToolResult(ok=False, error={"message": "canvas_id is required"})
        
        response = await client.get(
            canvas_id,
            params={"fields": "id,name,canvas_link"}
        )
        
        return ToolResult(
            ok=True,
            data={
                "canvas_id": response.get("id"),
                "name": response.get("name"),
                "preview_url": response.get("canvas_link"),
            }
        )
    except MetaApiError as exc:
        logger.error("preview_canvas_failed", canvas_id=canvas_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def clone_canvas_handler(arguments: Dict[str, Any]) -> ToolResult:
    """Clone an existing Instant Experience.
    
    Args:
        arguments: {
            "canvas_id": "123",
            "new_name": "Cloned Canvas"
        }
        
    Returns:
        ToolResult with cloned canvas ID
    """
    try:
        client = get_client()
        canvas_id = arguments.get("canvas_id")
        new_name = arguments.get("new_name")
        
        if not canvas_id:
            return ToolResult(ok=False, error={"message": "canvas_id is required"})
        
        # First, get the original canvas details
        original = await client.get(
            canvas_id,
            params={"fields": "name,body_elements,background_color,owner_page,business"}
        )
        
        # Create a new canvas with the same content
        clone_data = {
            "name": new_name or f"{original.get('name', 'Canvas')} (Copy)",
            "body_elements": original.get("body_elements", []),
            "background_color": original.get("background_color"),
            "is_published": False,  # Start as unpublished
        }
        
        business_id = original.get("business", {}).get("id")
        if not business_id:
            return ToolResult(ok=False, error={"message": "Unable to determine business_id from original canvas"})
        
        response = await client.post(
            f"{business_id}/canvas_elements",
            body=clone_data
        )
        
        return ToolResult(
            ok=True,
            data={
                "original_id": canvas_id,
                "cloned_id": response.get("id"),
                "message": "Canvas cloned successfully",
            }
        )
    except MetaApiError as exc:
        logger.error("clone_canvas_failed", canvas_id=canvas_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())

