/**
 * Order Management Tools
 */

import { z } from 'zod';
import type { TouchBistroApiClient } from '../lib/api-client.js';

export const orderTools = {
  touchbistro_list_orders: {
    description:
      'List all orders with optional filters (status, type, date range, server). Returns active, completed, and historical orders.',
    parameters: z.object({
      status: z
        .enum(['draft', 'pending', 'in_progress', 'ready', 'completed', 'voided', 'cancelled'])
        .optional()
        .describe('Filter by order status'),
      type: z
        .enum(['dine_in', 'takeout', 'delivery', 'curbside', 'drive_thru'])
        .optional()
        .describe('Filter by order type'),
      serverId: z.string().optional().describe('Filter by server ID'),
      dateFrom: z.string().optional().describe('Start date (ISO format)'),
      dateTo: z.string().optional().describe('End date (ISO format)'),
      page: z.number().optional().describe('Page number'),
      pageSize: z.number().optional().describe('Items per page'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const filter: any = {};
      if (params.status) filter.status = params.status;
      if (params.type) filter.type = params.type;
      if (params.serverId) filter.serverId = params.serverId;
      if (params.dateFrom) filter.dateFrom = params.dateFrom;
      if (params.dateTo) filter.dateTo = params.dateTo;

      const response = await client.getOrders({
        page: params.page,
        pageSize: params.pageSize,
        filter,
      });

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to fetch orders');
      }

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data, null, 2),
          },
        ],
      };
    },
  },

  touchbistro_get_order: {
    description: 'Get detailed information about a specific order including items, payments, and status.',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.getOrder(params.orderId);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to fetch order');
      }

      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data, null, 2),
          },
        ],
      };
    },
  },

  touchbistro_create_order: {
    description: 'Create a new order with initial items, table assignment, and server.',
    parameters: z.object({
      type: z.enum(['dine_in', 'takeout', 'delivery', 'curbside', 'drive_thru']).describe('Order type'),
      tableId: z.string().optional().describe('Table ID (for dine-in orders)'),
      customerId: z.string().optional().describe('Customer ID'),
      serverId: z.string().describe('Server/staff ID'),
      guestCount: z.number().optional().describe('Number of guests'),
      items: z
        .array(
          z.object({
            menuItemId: z.string(),
            quantity: z.number(),
            modifiers: z.array(z.object({ id: z.string(), name: z.string(), price: z.number() })).optional(),
            specialInstructions: z.string().optional(),
            seat: z.number().optional(),
          })
        )
        .optional()
        .describe('Initial order items'),
      notes: z.string().optional().describe('Order notes'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.createOrder(params);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to create order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order created successfully!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_update_order: {
    description: 'Update order details like guest count, notes, or special instructions.',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
      guestCount: z.number().optional().describe('Updated guest count'),
      notes: z.string().optional().describe('Updated notes'),
      specialInstructions: z.string().optional().describe('Special instructions'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const { orderId, ...updates } = params;
      const response = await client.updateOrder(orderId, updates);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to update order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order updated successfully!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_add_order_item: {
    description: 'Add an item to an existing order with modifiers and special instructions.',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
      menuItemId: z.string().describe('Menu item ID'),
      quantity: z.number().describe('Quantity'),
      modifiers: z
        .array(z.object({ id: z.string(), name: z.string(), price: z.number() }))
        .optional()
        .describe('Item modifiers'),
      specialInstructions: z.string().optional().describe('Special cooking instructions'),
      seat: z.number().optional().describe('Seat number'),
      courseNumber: z.number().optional().describe('Course number'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const { orderId, ...item } = params;
      const response = await client.addOrderItem(orderId, item);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to add item to order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Item added to order!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_update_order_item: {
    description: 'Update an existing order item (quantity, modifiers, instructions).',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
      itemId: z.string().describe('Order item ID'),
      quantity: z.number().optional().describe('Updated quantity'),
      modifiers: z
        .array(z.object({ id: z.string(), name: z.string(), price: z.number() }))
        .optional()
        .describe('Updated modifiers'),
      specialInstructions: z.string().optional().describe('Updated special instructions'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const { orderId, itemId, ...updates } = params;
      const response = await client.updateOrderItem(orderId, itemId, updates);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to update order item');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order item updated!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_remove_order_item: {
    description: 'Remove an item from an order.',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
      itemId: z.string().describe('Order item ID to remove'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.removeOrderItem(params.orderId, params.itemId);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to remove order item');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order item removed successfully!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_send_to_kitchen: {
    description: 'Send an order to the kitchen for preparation. Marks items as fired.',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.sendOrderToKitchen(params.orderId);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to send order to kitchen');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order sent to kitchen!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_complete_order: {
    description: 'Mark an order as completed (all items served, payment received).',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.completeOrder(params.orderId);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to complete order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order completed successfully!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_void_order: {
    description: 'Void an entire order with a reason (requires manager approval).',
    parameters: z.object({
      orderId: z.string().describe('Order ID'),
      reason: z.string().describe('Reason for voiding the order'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.voidOrder(params.orderId, params.reason);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to void order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order voided!\n\n${JSON.stringify(response.data, null, 2)}`,
          },
        ],
      };
    },
  },

  touchbistro_split_order: {
    description: 'Split an order by items or amount across multiple checks.',
    parameters: z.object({
      orderId: z.string().describe('Order ID to split'),
      splits: z
        .array(
          z.object({
            items: z.array(z.string()).describe('Order item IDs for this split'),
            amount: z.number().optional().describe('Fixed amount (alternative to items)'),
          })
        )
        .describe('Split configurations'),
    }),
    handler: async (params: any, client: TouchBistroApiClient) => {
      const response = await client.splitOrder(params.orderId, params.splits);

      if (!response.success) {
        throw new Error(response.error?.message || 'Failed to split order');
      }

      return {
        content: [
          {
            type: 'text',
            text: `Order split into ${params.splits.length} checks!\n\n${JSON.stringify(
              response.data,
              null,
              2
            )}`,
          },
        ],
      };
    },
  },
};
