"""
Restaurant Agent Specialized Tools

Tools specific to restaurant operations:
- Reservations management
- Table management
- Menu operations
- Kitchen order tracking
"""
from typing import Any, Dict
from app.tools.base import ReadOnlyTool, WriteTool, ToolParameter, ParameterType, ToolResult
from app.tools.registry import register_tool


@register_tool
class GetReservationsTool(ReadOnlyTool):
    """Get restaurant reservations"""

    name = "get_reservations"
    description = "Get list of reservations for a specific date or date range"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Date for reservations (YYYY-MM-DD format)",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Start date for range query",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="End date for range query",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: confirmed, pending, cancelled, completed",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_reservations(**params)
            return ToolResult.success_result(data, "Reservations retrieved successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get reservations: {str(e)}")


@register_tool
class GetReservationDetailsTool(ReadOnlyTool):
    """Get details of a specific reservation"""

    name = "get_reservation_details"
    description = "Get detailed information about a specific reservation including guest info, special requests"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="reservation_id",
            type=ParameterType.STRING,
            description="Reservation ID",
            required=True
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_reservation_details(**params)
            return ToolResult.success_result(data, "Reservation details retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get reservation details: {str(e)}")


@register_tool
class CreateReservationTool(WriteTool):
    """Create a new reservation"""

    name = "create_reservation"
    description = "Create a new table reservation"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="guest_name",
            type=ParameterType.STRING,
            description="Guest name for the reservation",
            required=True
        ),
        ToolParameter(
            name="guest_phone",
            type=ParameterType.STRING,
            description="Guest phone number",
            required=True
        ),
        ToolParameter(
            name="guest_email",
            type=ParameterType.STRING,
            description="Guest email address",
            required=False
        ),
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Reservation date (YYYY-MM-DD)",
            required=True
        ),
        ToolParameter(
            name="time",
            type=ParameterType.STRING,
            description="Reservation time (HH:MM)",
            required=True
        ),
        ToolParameter(
            name="party_size",
            type=ParameterType.INTEGER,
            description="Number of guests",
            required=True
        ),
        ToolParameter(
            name="special_requests",
            type=ParameterType.STRING,
            description="Any special requests or notes",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.create_reservation(**params)
            return ToolResult.success_result(data, "Reservation created successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to create reservation: {str(e)}")


@register_tool
class UpdateReservationTool(WriteTool):
    """Update an existing reservation"""

    name = "update_reservation"
    description = "Update reservation details (time, party size, status)"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="reservation_id",
            type=ParameterType.STRING,
            description="Reservation ID to update",
            required=True
        ),
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="New date (YYYY-MM-DD)",
            required=False
        ),
        ToolParameter(
            name="time",
            type=ParameterType.STRING,
            description="New time (HH:MM)",
            required=False
        ),
        ToolParameter(
            name="party_size",
            type=ParameterType.INTEGER,
            description="New party size",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="New status: confirmed, cancelled, no_show",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.update_reservation(**params)
            return ToolResult.success_result(data, "Reservation updated successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to update reservation: {str(e)}")


@register_tool
class GetTablesTool(ReadOnlyTool):
    """Get table availability and status"""

    name = "get_tables"
    description = "Get list of tables with their current status and availability"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: available, occupied, reserved, cleaning",
            required=False
        ),
        ToolParameter(
            name="capacity_min",
            type=ParameterType.INTEGER,
            description="Minimum seating capacity",
            required=False
        ),
        ToolParameter(
            name="section",
            type=ParameterType.STRING,
            description="Restaurant section (indoor, outdoor, private, bar)",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_tables(**params)
            return ToolResult.success_result(data, "Tables retrieved successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get tables: {str(e)}")


@register_tool
class GetMenuTool(ReadOnlyTool):
    """Get restaurant menu items"""

    name = "get_menu"
    description = "Get menu items with prices, descriptions, and availability"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="category",
            type=ParameterType.STRING,
            description="Menu category: appetizers, mains, desserts, beverages",
            required=False
        ),
        ToolParameter(
            name="dietary",
            type=ParameterType.STRING,
            description="Dietary filter: vegetarian, vegan, gluten_free, halal",
            required=False
        ),
        ToolParameter(
            name="available_only",
            type=ParameterType.BOOLEAN,
            description="Show only currently available items",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_menu(**params)
            return ToolResult.success_result(data, "Menu retrieved successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get menu: {str(e)}")


@register_tool
class GetKitchenOrdersTool(ReadOnlyTool):
    """Get kitchen orders queue"""

    name = "get_kitchen_orders"
    description = "Get current kitchen orders with preparation status"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Order status: pending, preparing, ready, served",
            required=False
        ),
        ToolParameter(
            name="table_id",
            type=ParameterType.STRING,
            description="Filter by specific table",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_kitchen_orders(**params)
            return ToolResult.success_result(data, "Kitchen orders retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get kitchen orders: {str(e)}")


@register_tool
class UpdateKitchenOrderStatusTool(WriteTool):
    """Update kitchen order status"""

    name = "update_kitchen_order_status"
    description = "Update the preparation status of a kitchen order"
    category = "restaurant"
    agent_types = ["restaurant", "hospitality"]

    parameters = [
        ToolParameter(
            name="order_id",
            type=ParameterType.STRING,
            description="Kitchen order ID",
            required=True
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="New status: preparing, ready, served",
            required=True
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Additional notes",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.update_kitchen_order_status(**params)
            return ToolResult.success_result(data, "Kitchen order status updated")
        except Exception as e:
            return ToolResult.error_result(f"Failed to update order status: {str(e)}")
