"""Events Handler - OpenPanel event tracking operations (11 tools)"""

import json
from typing import Any

from plugins.openpanel.client import OpenPanelClient


def get_tool_specifications() -> list[dict[str, Any]]:
    """Return tool specifications for ToolGenerator (11 tools)"""
    return [
        {
            "name": "track_event",
            "method_name": "track_event",
            "description": "Track a custom event with properties. Events can have any custom properties for analytics.",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "Event name (e.g., 'button_clicked', 'purchase_completed', 'page_viewed')",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": 'Custom properties for the event (e.g., {"product_id": "123", "price": 99.99})',
                    },
                    "profile_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User/profile ID to associate with the event",
                    },
                    "timestamp": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Event timestamp (ISO 8601 format, defaults to now)",
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP for geolocation tracking",
                    },
                    "user_agent": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User agent for device detection",
                    },
                },
                "required": ["name"],
            },
            "scope": "write",
        },
        {
            "name": "track_page_view",
            "method_name": "track_page_view",
            "description": "Track a page view event with URL and referrer information.",
            "schema": {
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Page path (e.g., '/products/123', '/blog/post-title')",
                    },
                    "title": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Page title",
                    },
                    "referrer": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Referrer URL",
                    },
                    "profile_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User/profile ID",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": "Additional properties",
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP for geolocation",
                    },
                    "user_agent": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User agent for device detection",
                    },
                },
                "required": ["path"],
            },
            "scope": "write",
        },
        {
            "name": "track_screen_view",
            "method_name": "track_screen_view",
            "description": "Track a screen view event for mobile applications.",
            "schema": {
                "type": "object",
                "properties": {
                    "screen_name": {
                        "type": "string",
                        "description": "Screen name (e.g., 'HomeScreen', 'ProductDetail')",
                    },
                    "screen_class": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Screen class/component name",
                    },
                    "profile_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User/profile ID",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": "Additional properties",
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP",
                    },
                    "user_agent": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User agent",
                    },
                },
                "required": ["screen_name"],
            },
            "scope": "write",
        },
        {
            "name": "identify_user",
            "method_name": "identify_user",
            "description": "Identify a user and set their profile properties. Use this to associate events with users.",
            "schema": {
                "type": "object",
                "properties": {
                    "profile_id": {
                        "type": "string",
                        "description": "Unique identifier for the user",
                    },
                    "email": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User's email address",
                    },
                    "first_name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User's first name",
                    },
                    "last_name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User's last name",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": 'Additional profile properties (e.g., {"plan": "premium", "company": "Acme"})',
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP",
                    },
                    "user_agent": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User agent",
                    },
                },
                "required": ["profile_id"],
            },
            "scope": "write",
        },
        {
            "name": "set_user_properties",
            "method_name": "set_user_properties",
            "description": "Update properties for an existing user profile.",
            "schema": {
                "type": "object",
                "properties": {
                    "profile_id": {"type": "string", "description": "User's profile ID"},
                    "properties": {
                        "type": "object",
                        "description": "Properties to set/update on the profile",
                    },
                },
                "required": ["profile_id", "properties"],
            },
            "scope": "write",
        },
        {
            "name": "increment_property",
            "method_name": "increment_property",
            "description": "Increment a numeric property on a user profile. IMPORTANT: Profile must exist first (use identify_user). Property must be numeric.",
            "schema": {
                "type": "object",
                "properties": {
                    "profile_id": {"type": "string", "description": "User's profile ID"},
                    "property_name": {
                        "type": "string",
                        "description": "Name of the property to increment",
                    },
                    "value": {
                        "type": "integer",
                        "description": "Amount to increment by",
                        "default": 1,
                    },
                },
                "required": ["profile_id", "property_name"],
            },
            "scope": "write",
        },
        {
            "name": "decrement_property",
            "method_name": "decrement_property",
            "description": "Decrement a numeric property on a user profile. IMPORTANT: Profile must exist first (use identify_user). Property must be numeric.",
            "schema": {
                "type": "object",
                "properties": {
                    "profile_id": {"type": "string", "description": "User's profile ID"},
                    "property_name": {
                        "type": "string",
                        "description": "Name of the property to decrement",
                    },
                    "value": {
                        "type": "integer",
                        "description": "Amount to decrement by",
                        "default": 1,
                    },
                },
                "required": ["profile_id", "property_name"],
            },
            "scope": "write",
        },
        {
            "name": "create_group",
            "method_name": "create_group",
            "description": "Create or update a group (e.g., company, workspace, team). Groups can be associated with events and profiles.",
            "schema": {
                "type": "object",
                "properties": {
                    "group_id": {
                        "type": "string",
                        "description": "Unique group identifier",
                    },
                    "group_type": {
                        "type": "string",
                        "description": "Group category (e.g., 'company', 'workspace', 'team')",
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name for the group",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": 'Custom group properties (e.g., {"plan": "enterprise", "size": 50})',
                    },
                },
                "required": ["group_id", "group_type", "name"],
            },
            "scope": "write",
        },
        {
            "name": "assign_group",
            "method_name": "assign_group",
            "description": "Assign a user to one or more groups. If no profile_id is provided, falls back to device ID.",
            "schema": {
                "type": "object",
                "properties": {
                    "group_ids": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of group IDs to assign the user to",
                        "minItems": 1,
                    },
                    "profile_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User profile ID (falls back to device ID if not provided)",
                    },
                },
                "required": ["group_ids"],
            },
            "scope": "write",
        },
        {
            "name": "track_revenue",
            "method_name": "track_revenue",
            "description": "Track a revenue/purchase event with amount and currency.",
            "schema": {
                "type": "object",
                "properties": {
                    "amount": {"type": "number", "description": "Revenue amount"},
                    "currency": {
                        "type": "string",
                        "description": "Currency code (e.g., 'USD', 'EUR', 'IRR')",
                        "default": "USD",
                    },
                    "product_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product ID",
                    },
                    "product_name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product name",
                    },
                    "order_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Order/transaction ID",
                    },
                    "profile_id": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User's profile ID",
                    },
                    "properties": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": "Additional properties",
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP",
                    },
                },
                "required": ["amount"],
            },
            "scope": "write",
        },
        {
            "name": "track_batch",
            "method_name": "track_batch",
            "description": "Track multiple events in a single request for efficiency.",
            "schema": {
                "type": "object",
                "properties": {
                    "events": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string"},
                                "properties": {"type": "object"},
                                "profile_id": {"type": "string"},
                                "timestamp": {"type": "string"},
                            },
                            "required": ["name"],
                        },
                        "description": "Array of events to track",
                        "minItems": 1,
                        "maxItems": 100,
                    },
                    "client_ip": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Client IP for all events",
                    },
                    "user_agent": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "User agent for all events",
                    },
                },
                "required": ["events"],
            },
            "scope": "write",
        },
    ]


# =====================
# Event Tracking Functions (10)
# =====================


async def track_event(
    client: OpenPanelClient,
    name: str,
    properties: dict[str, Any] | None = None,
    profile_id: str | None = None,
    timestamp: str | None = None,
    client_ip: str | None = None,
    user_agent: str | None = None,
) -> str:
    """Track a custom event"""
    try:
        result = await client.track_event(
            name=name,
            properties=properties,
            profile_id=profile_id,
            timestamp=timestamp,
            client_ip=client_ip,
            user_agent=user_agent,
        )

        return json.dumps(
            {
                "success": True,
                "event": name,
                "profile_id": profile_id,
                "message": f"Event '{name}' tracked successfully",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def track_page_view(
    client: OpenPanelClient,
    path: str,
    title: str | None = None,
    referrer: str | None = None,
    profile_id: str | None = None,
    properties: dict[str, Any] | None = None,
    client_ip: str | None = None,
    user_agent: str | None = None,
) -> str:
    """Track a page view event"""
    try:
        event_properties = {
            "path": path,
        }
        if title:
            event_properties["title"] = title
        if referrer:
            event_properties["referrer"] = referrer
        if properties:
            event_properties.update(properties)

        result = await client.track_event(
            name="page_view",
            properties=event_properties,
            profile_id=profile_id,
            client_ip=client_ip,
            user_agent=user_agent,
        )

        return json.dumps(
            {
                "success": True,
                "event": "page_view",
                "path": path,
                "message": f"Page view tracked for '{path}'",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def track_screen_view(
    client: OpenPanelClient,
    screen_name: str,
    screen_class: str | None = None,
    profile_id: str | None = None,
    properties: dict[str, Any] | None = None,
    client_ip: str | None = None,
    user_agent: str | None = None,
) -> str:
    """Track a screen view event for mobile"""
    try:
        event_properties = {
            "screen_name": screen_name,
        }
        if screen_class:
            event_properties["screen_class"] = screen_class
        if properties:
            event_properties.update(properties)

        result = await client.track_event(
            name="screen_view",
            properties=event_properties,
            profile_id=profile_id,
            client_ip=client_ip,
            user_agent=user_agent,
        )

        return json.dumps(
            {
                "success": True,
                "event": "screen_view",
                "screen_name": screen_name,
                "message": f"Screen view tracked for '{screen_name}'",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def identify_user(
    client: OpenPanelClient,
    profile_id: str,
    email: str | None = None,
    first_name: str | None = None,
    last_name: str | None = None,
    properties: dict[str, Any] | None = None,
    client_ip: str | None = None,
    user_agent: str | None = None,
) -> str:
    """Identify a user with profile data"""
    try:
        result = await client.identify_user(
            profile_id=profile_id,
            email=email,
            first_name=first_name,
            last_name=last_name,
            properties=properties,
            client_ip=client_ip,
            user_agent=user_agent,
        )

        return json.dumps(
            {
                "success": True,
                "profile_id": profile_id,
                "email": email,
                "message": f"User '{profile_id}' identified successfully",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def set_user_properties(
    client: OpenPanelClient, profile_id: str, properties: dict[str, Any]
) -> str:
    """Update properties for a user profile"""
    try:
        result = await client.identify_user(profile_id=profile_id, properties=properties)

        return json.dumps(
            {
                "success": True,
                "profile_id": profile_id,
                "properties_set": list(properties.keys()),
                "message": f"Properties updated for user '{profile_id}'",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def increment_property(
    client: OpenPanelClient, profile_id: str, property_name: str, value: int = 1
) -> str:
    """Increment a numeric property on a profile"""
    try:
        result = await client.increment_property(
            profile_id=profile_id, property_name=property_name, value=value
        )

        return json.dumps(
            {
                "success": True,
                "profile_id": profile_id,
                "property": property_name,
                "increment_by": value,
                "message": f"Property '{property_name}' incremented by {value}",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        error_str = str(e)
        hint = ""
        if "500" in error_str:
            hint = " (Hint: Profile must exist and property must be numeric. Try identifying the user first with identify_user.)"
        return json.dumps(
            {
                "success": False,
                "error": error_str + hint,
                "profile_id": profile_id,
                "property": property_name,
            },
            indent=2,
            ensure_ascii=False,
        )


async def decrement_property(
    client: OpenPanelClient, profile_id: str, property_name: str, value: int = 1
) -> str:
    """Decrement a numeric property on a profile"""
    try:
        result = await client.decrement_property(
            profile_id=profile_id, property_name=property_name, value=value
        )

        return json.dumps(
            {
                "success": True,
                "profile_id": profile_id,
                "property": property_name,
                "decrement_by": value,
                "message": f"Property '{property_name}' decremented by {value}",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        error_str = str(e)
        hint = ""
        if "500" in error_str:
            hint = " (Hint: Profile must exist and property must be numeric. Try identifying the user first with identify_user.)"
        return json.dumps(
            {
                "success": False,
                "error": error_str + hint,
                "profile_id": profile_id,
                "property": property_name,
            },
            indent=2,
            ensure_ascii=False,
        )


async def create_group(
    client: OpenPanelClient,
    group_id: str,
    group_type: str,
    name: str,
    properties: dict[str, Any] | None = None,
) -> str:
    """Create or update a group"""
    try:
        result = await client.track_group(
            group_id=group_id, group_type=group_type, name=name, properties=properties
        )
        return json.dumps(
            {
                "success": True,
                "group_id": group_id,
                "group_type": group_type,
                "name": name,
                "message": f"Group '{name}' ({group_type}) created/updated",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def assign_group(
    client: OpenPanelClient,
    group_ids: list[str],
    profile_id: str | None = None,
) -> str:
    """Assign a user to groups"""
    try:
        result = await client.assign_group(group_ids=group_ids, profile_id=profile_id)
        return json.dumps(
            {
                "success": True,
                "group_ids": group_ids,
                "profile_id": profile_id,
                "message": f"User assigned to {len(group_ids)} group(s)",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def track_revenue(
    client: OpenPanelClient,
    amount: float,
    currency: str = "USD",
    product_id: str | None = None,
    product_name: str | None = None,
    order_id: str | None = None,
    profile_id: str | None = None,
    properties: dict[str, Any] | None = None,
    client_ip: str | None = None,
) -> str:
    """Track a revenue/purchase event"""
    try:
        event_properties = {
            "amount": amount,
            "currency": currency,
        }
        if product_id:
            event_properties["product_id"] = product_id
        if product_name:
            event_properties["product_name"] = product_name
        if order_id:
            event_properties["order_id"] = order_id
        if properties:
            event_properties.update(properties)

        result = await client.track_event(
            name="revenue", properties=event_properties, profile_id=profile_id, client_ip=client_ip
        )

        return json.dumps(
            {
                "success": True,
                "event": "revenue",
                "amount": amount,
                "currency": currency,
                "order_id": order_id,
                "message": f"Revenue of {amount} {currency} tracked",
                "response": result,
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)


async def track_batch(
    client: OpenPanelClient,
    events: list[dict[str, Any]],
    client_ip: str | None = None,
    user_agent: str | None = None,
) -> str:
    """Track multiple events in batch"""
    try:
        results = []
        errors = []

        for event in events:
            try:
                await client.track_event(
                    name=event.get("name"),
                    properties=event.get("properties"),
                    profile_id=event.get("profile_id"),
                    timestamp=event.get("timestamp"),
                    client_ip=client_ip,
                    user_agent=user_agent,
                )
                results.append({"name": event.get("name"), "success": True})
            except Exception as e:
                errors.append({"name": event.get("name"), "error": str(e)})

        return json.dumps(
            {
                "success": len(errors) == 0,
                "total": len(events),
                "tracked": len(results),
                "failed": len(errors),
                "results": results,
                "errors": errors if errors else None,
                "message": f"Batch tracked {len(results)}/{len(events)} events",
            },
            indent=2,
            ensure_ascii=False,
        )
    except Exception as e:
        return json.dumps({"success": False, "error": str(e)}, indent=2, ensure_ascii=False)
