"""Batch tools for MCP."""

from typing import Any

from mcp.types import TextContent, Tool

from ..client import Platform2StepClient

BATCH_TOOLS: list[Tool] = [
    Tool(
        name="create_batch",
        description="""Create a batch of operations (1-50). The ONLY way to mutate categories, services, providers, bookings, locations, and clients. Operations: create, update, delete, activate, deactivate. delete: categories (permanent), services (hides: active=false + visible=false), bookings (cancels), clients (soft delete). deactivate: services (active=false, stays visible), providers, locations. activate: services, providers (may fail if plan limit reached), locations. IMPORTANT: Providers and locations do NOT support delete. If the user asks to "delete" a provider or location, explain that deletion is not available and offer to deactivate instead. Location country/timezone are auto-resolved from the company. CLIENTS: Before creating a client, call list_custom_attributes to check for mandatory attributes and include them in the payload. The user must confirm in the browser before operations execute.""",
        inputSchema={
            "type": "object",
            "properties": {
                "company_id": {
                    "type": "integer",
                    "description": "Company ID",
                },
                "description": {
                    "type": "string",
                    "description": "Description of the batch for the user",
                },
                "operations": {
                    "type": "array",
                    "maxItems": 50,
                    "description": "List of operations to execute",
                    "items": {
                        "type": "object",
                        "properties": {
                            "operation": {
                                "type": "string",
                                "enum": [
                                    "create",
                                    "update",
                                    "delete",
                                    "activate",
                                    "deactivate",
                                ],
                                "description": "Operation type",
                            },
                            "resource": {
                                "type": "string",
                                "enum": [
                                    "category",
                                    "service",
                                    "booking",
                                    "provider",
                                    "location",
                                    "client",
                                ],
                                "description": "Resource type",
                            },
                            "resource_id": {
                                "type": "integer",
                                "description": "Resource ID (required for update/delete/activate/deactivate)",
                            },
                            "payload": {
                                "type": "object",
                                "description": (
                                    "REQUIRED for create/update. Omit for delete/activate/deactivate. "
                                    "For update: include ONLY the fields you want to change. "
                                    "For create: include all required fields."
                                ),
                                "properties": {
                                    # Category fields
                                    "name": {
                                        "type": "string",
                                        "description": "Resource name (required for create category/service)",
                                    },
                                    "order": {
                                        "type": "integer",
                                        "description": "Display order (category)",
                                    },
                                    # Service fields
                                    "service_category_id": {
                                        "type": "integer",
                                        "description": "Category ID (required for create service)",
                                    },
                                    "duration": {
                                        "type": "integer",
                                        "description": "Duration in minutes (service)",
                                    },
                                    "price": {
                                        "type": "integer",
                                        "description": "Price in cents (service)",
                                    },
                                    "active": {
                                        "type": "boolean",
                                        "description": "Active status (service). For providers/locations, use activate/deactivate operations instead.",
                                    },
                                    "description": {
                                        "type": "string",
                                        "description": "Description (service)",
                                    },
                                    "favorite": {
                                        "type": "boolean",
                                        "description": "Mark as favorite service (service, default: false)",
                                    },
                                    "show_price": {
                                        "type": "boolean",
                                        "description": "Show price to clients (service, default: true)",
                                    },
                                    "show_duration": {
                                        "type": "boolean",
                                        "description": "Show duration to clients (service, default: true)",
                                    },
                                    "is_video": {
                                        "type": "boolean",
                                        "description": "Video service (service, default: false)",
                                    },
                                    "outcall": {
                                        "type": "boolean",
                                        "description": "Outcall service at client location (service, default: false)",
                                    },
                                    "has_sales_taxes": {
                                        "type": "boolean",
                                        "description": "Apply sales taxes (service, default: false)",
                                    },
                                    "use_time_resource": {
                                        "type": "boolean",
                                        "description": "Use time resource (service, default: true)",
                                    },
                                    "online_payment": {
                                        "type": "object",
                                        "description": "Online payment settings (service, default: {amount: 0, mode: 'NOT_AVAILABLE'})",
                                        "properties": {
                                            "amount": {
                                                "type": "number",
                                                "description": "Payment amount",
                                            },
                                            "mode": {
                                                "type": "string",
                                                "enum": [
                                                    "NOT_AVAILABLE",
                                                    "OPTIONAL",
                                                    "REQUIRED",
                                                ],
                                                "description": "Payment mode",
                                            },
                                        },
                                        "required": ["amount", "mode"],
                                        "additionalProperties": False,
                                    },
                                    # Booking fields
                                    "service_id": {
                                        "type": "integer",
                                        "description": "Service ID (required for create booking)",
                                    },
                                    "provider_id": {
                                        "type": "integer",
                                        "description": "Provider ID (required for create booking)",
                                    },
                                    "client_id": {
                                        "type": "integer",
                                        "description": "Client ID (required for create booking)",
                                    },
                                    "start_time": {
                                        "type": "string",
                                        "description": "Start datetime in the location's local time, without timezone offset. Format: YYYY-MM-DDTHH:MM:SS. Example: 2026-03-03T11:00:00 (required for create booking)",
                                    },
                                    "notes": {
                                        "type": "string",
                                        "description": "Notes (booking)",
                                    },
                                    "status_id": {
                                        "type": "integer",
                                        "description": "Booking status: 1=Reservado (required for create, only value allowed). For update: 1,2,3,6,7,8",
                                    },
                                    "creative_source": {
                                        "type": "string",
                                        "description": "Creative source (booking, default: 'schedule')",
                                    },
                                    "send_mail": {
                                        "type": "boolean",
                                        "description": "Send email notification (booking, default: false)",
                                    },
                                    "send_whatsapp": {
                                        "type": "boolean",
                                        "description": "Send WhatsApp notification (booking, default: false)",
                                    },
                                    "send_email_reminder": {
                                        "type": "boolean",
                                        "description": "Send email reminder (booking, default: false)",
                                    },
                                    "send_whatsapp_reminder": {
                                        "type": "boolean",
                                        "description": "Send WhatsApp reminder (booking, default: false)",
                                    },
                                    # Provider fields
                                    "location_id": {
                                        "type": "integer",
                                        "description": "Location ID (required for create booking and provider operations)",
                                    },
                                    "public_name": {
                                        "type": "string",
                                        "description": "Public name (provider)",
                                    },
                                    "online_booking": {
                                        "type": "boolean",
                                        "description": "Online booking enabled (provider)",
                                    },
                                    "times": {
                                        "type": "array",
                                        "description": "Weekly schedule. For providers: ISO 8601 (2000-01-01T09:00:00.000Z). For locations: simple HH:MM (09:00). Omitted days = closed. For location create: omit entirely to create with all days closed.",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "day_id": {
                                                    "type": "integer",
                                                    "description": "Day of week: 1=Monday, 2=Tuesday, ..., 7=Sunday",
                                                },
                                                "open": {
                                                    "type": "string",
                                                    "description": "Start time as ISO 8601 (date ignored, only time matters). Example: 2000-01-01T09:00:00.000Z",
                                                },
                                                "close": {
                                                    "type": "string",
                                                    "description": "End time as ISO 8601 (date ignored, only time matters). Example: 2000-01-01T18:00:00.000Z",
                                                },
                                                "breaks": {
                                                    "type": "array",
                                                    "description": "Optional breaks within the day (e.g. lunch). Omit or use empty array for no breaks.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "open": {
                                                                "type": "string",
                                                                "description": "Break start time as ISO 8601. Example: 2000-01-01T13:00:00.000Z",
                                                            },
                                                            "close": {
                                                                "type": "string",
                                                                "description": "Break end time as ISO 8601. Example: 2000-01-01T14:00:00.000Z",
                                                            },
                                                        },
                                                        "required": ["open", "close"],
                                                        "additionalProperties": False,
                                                    },
                                                },
                                            },
                                            "required": ["day_id", "open", "close"],
                                            "additionalProperties": False,
                                        },
                                    },
                                    # Location fields
                                    "email": {
                                        "type": "string",
                                        "description": "Email (required for create location)",
                                    },
                                    "phone": {
                                        "type": "string",
                                        "description": "Phone number (optional for location, max 255 chars)",
                                    },
                                    "latitude": {
                                        "type": "number",
                                        "description": "Latitude (optional for location, -90 to 90. Must be sent with longitude)",
                                    },
                                    "longitude": {
                                        "type": "number",
                                        "description": "Longitude (optional for location, -180 to 180. Must be sent with latitude)",
                                    },
                                    "address": {
                                        "description": "For locations: array of Google Maps address components (required for create). For clients: plain string (e.g. 'Av. Providencia 123').",
                                        "anyOf": [
                                            {
                                                "type": "array",
                                                "items": {
                                                    "type": "object",
                                                    "properties": {
                                                        "long_name": {
                                                            "type": "string",
                                                            "description": "Full name of address component",
                                                        },
                                                        "short_name": {
                                                            "type": "string",
                                                            "description": "Abbreviated name",
                                                        },
                                                        "types": {
                                                            "type": "array",
                                                            "items": {"type": "string"},
                                                            "description": "Component types (e.g. route, locality, country)",
                                                        },
                                                    },
                                                    "required": ["long_name", "types"],
                                                    "additionalProperties": False,
                                                },
                                            },
                                            {
                                                "type": "string",
                                            },
                                        ],
                                    },
                                    # Client fields
                                    "first_name": {
                                        "type": "string",
                                        "description": "Client first name (required for create client)",
                                    },
                                    "last_name": {
                                        "type": "string",
                                        "description": "Client last name",
                                    },
                                    "identification_number": {
                                        "type": "string",
                                        "description": "ID/RUT number (client)",
                                    },
                                    "district": {
                                        "type": "string",
                                        "description": "District (client)",
                                    },
                                    "city": {
                                        "type": "string",
                                        "description": "City (client)",
                                    },
                                    "region": {
                                        "type": "string",
                                        "description": "Region (client)",
                                    },
                                    "age": {
                                        "type": "integer",
                                        "description": "Age (client, positive integer)",
                                    },
                                    "gender": {
                                        "type": "integer",
                                        "description": "Gender: 0=other, 1=female, 2=male (client, default: 0)",
                                    },
                                    "birth_day": {
                                        "type": "integer",
                                        "description": "Birth day (client)",
                                    },
                                    "birth_month": {
                                        "type": "integer",
                                        "description": "Birth month (client)",
                                    },
                                    "birth_year": {
                                        "type": "integer",
                                        "description": "Birth year (client)",
                                    },
                                    # Client custom attributes
                                    "custom_attributes": {
                                        "type": "array",
                                        "description": "Custom attribute values for client create/update. Call list_custom_attributes first to discover available attributes.",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "description": "Custom attribute ID",
                                                },
                                                "value": {
                                                    "anyOf": [
                                                        {"type": "string"},
                                                        {"type": "null"},
                                                    ],
                                                    "description": "Attribute value (string or null)",
                                                },
                                            },
                                            "required": ["id", "value"],
                                            "additionalProperties": False,
                                        },
                                    },
                                    "force": {
                                        "type": "boolean",
                                        "description": "Skip mandatory custom_attribute validation. Default: false. Only set to true if explicitly requested by the user or as a fallback after a failed attempt.",
                                    },
                                    # Shared fields
                                    "company_id": {
                                        "type": "integer",
                                        "description": "Company ID (required for create)",
                                    },
                                },
                                "additionalProperties": False,
                            },
                        },
                        "required": ["operation", "resource"],
                        "additionalProperties": False,
                    },
                },
            },
            "required": ["operations", "company_id"],
            "additionalProperties": False,
        },
    ),
    Tool(
        name="get_batch_status",
        description="""Get the status of a batch of operations.

Possible statuses:
- pending: Waiting for user confirmation
- confirmed: All operations executed successfully
- rejected: User rejected the batch
- expired: Batch expired without confirmation
- partial: Some operations failed during execution""",
        inputSchema={
            "type": "object",
            "properties": {
                "batch_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Batch ID (UUID)",
                },
            },
            "required": ["batch_id"],
            "additionalProperties": False,
        },
    ),
]


async def handle_batch_tool(
    name: str,
    arguments: dict[str, Any],
    client: Platform2StepClient,
) -> list[TextContent]:
    """Handle batch tool calls.

    Args:
        name: Tool name.
        arguments: Tool arguments.
        client: Platform2Step HTTP client.

    Returns:
        List of TextContent with the result.
    """
    if name == "create_batch":
        result = await client.create_batch(
            operations=arguments["operations"],
            company_id=arguments["company_id"],
            description=arguments.get("description"),
        )

        operations_preview = ""
        if result.operations:
            for op in result.operations:
                operations_preview += (
                    f"  {op.get('position', '?')}. {op.get('operation')} "
                    f"{op.get('resource')}"
                )
                if op.get("resource_id"):
                    operations_preview += f" (ID: {op['resource_id']})"
                preview = op.get("preview") or {}
                if isinstance(preview, dict) and "custom_attributes" in preview:
                    ca = preview["custom_attributes"]
                    count = len(ca) if isinstance(ca, list) else 0
                    operations_preview += f" (+{count} custom attributes)"
                operations_preview += "\n"

        return [
            TextContent(
                type="text",
                text=f"""Batch created successfully.

batch_id: {result.batch_id}
status: {result.status}
operations_count: {result.operations_count}
expires_at: {result.expires_at}
{f"description: {result.description}" if result.description else ""}

Operations:
{operations_preview if operations_preview else "(see operations in AgendaPro)"}

The user must confirm this batch in AgendaPro to execute all operations.
Confirm or reject all {result.operations_count} operations: {result.get_confirm_url(client.public_url)}""",
            )
        ]

    elif name == "get_batch_status":
        result = await client.get_batch_status(
            batch_id=arguments["batch_id"],
        )

        status_emoji = {
            "pending": "[PENDING]",
            "confirmed": "[CONFIRMED]",
            "rejected": "[REJECTED]",
            "expired": "[EXPIRED]",
            "partial": "[PARTIAL]",
        }
        emoji = status_emoji.get(result.status, "[?]")

        operations_info = ""
        if result.operations:
            for op in result.operations:
                op_status = op.get("status", "pending")
                operations_info += (
                    f"  {op.get('position', '?')}. [{op_status.upper()}] "
                    f"{op.get('operation')} {op.get('resource')}"
                )
                if op.get("resource_id"):
                    operations_info += f" (ID: {op['resource_id']})"
                operations_info += "\n"

        text = f"""{emoji} Batch Status: {result.status}

batch_id: {result.batch_id}
operations_count: {result.operations_count}
executed_count: {result.executed_count}
failed_count: {result.failed_count}
confirmable: {result.confirmable}
expires_at: {result.expires_at}
"""

        if result.description:
            text += f"description: {result.description}\n"

        if operations_info:
            text += f"\nOperations:\n{operations_info}"

        return [TextContent(type="text", text=text)]

    raise ValueError(f"Unknown batch tool: {name}")
