import type { BigCommerceClient } from '../clients/bigcommerce.js';
import type { Order, OrderProduct, ShippingAddress } from '../types/index.js';

export function registerOrderTools(client: BigCommerceClient) {
  return {
    // Order CRUD Operations
    bigcommerce_list_orders: {
      description: 'List all orders with optional filters (status, date range, customer, email, payment method)',
      parameters: {
        type: 'object' as const,
        properties: {
          status_id: { type: 'number', description: 'Filter by status ID (e.g., 1=Pending, 2=Shipped, 10=Completed, 11=Awaiting Payment)' },
          customer_id: { type: 'number', description: 'Filter by customer ID' },
          email: { type: 'string', description: 'Filter by customer email' },
          min_date_created: { type: 'string', description: 'Minimum creation date (ISO 8601 format)' },
          max_date_created: { type: 'string', description: 'Maximum creation date (ISO 8601 format)' },
          min_date_modified: { type: 'string', description: 'Minimum modification date (ISO 8601 format)' },
          max_date_modified: { type: 'string', description: 'Maximum modification date (ISO 8601 format)' },
          payment_method: { type: 'string', description: 'Filter by payment method' },
          min_total: { type: 'number', description: 'Minimum order total' },
          max_total: { type: 'number', description: 'Maximum order total' },
          is_deleted: { type: 'boolean', description: 'Include deleted orders' },
          page: { type: 'number', description: 'Page number (default: 1)' },
          limit: { type: 'number', description: 'Items per page (default: 50, max: 250)' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const queryParams: Record<string, string | number> = {};
        if (params.status_id) queryParams.status_id = params.status_id as number;
        if (params.customer_id) queryParams.customer_id = params.customer_id as number;
        if (params.email) queryParams.email = params.email as string;
        if (params.min_date_created) queryParams['min_date_created'] = params.min_date_created as string;
        if (params.max_date_created) queryParams['max_date_created'] = params.max_date_created as string;
        if (params.min_date_modified) queryParams['min_date_modified'] = params.min_date_modified as string;
        if (params.max_date_modified) queryParams['max_date_modified'] = params.max_date_modified as string;
        if (params.payment_method) queryParams.payment_method = params.payment_method as string;
        if (params.min_total) queryParams['min_total'] = params.min_total as number;
        if (params.max_total) queryParams['max_total'] = params.max_total as number;
        if (params.is_deleted !== undefined) queryParams.is_deleted = params.is_deleted ? 'true' : 'false';

        const page = (params.page as number) || 1;
        const limit = (params.limit as number) || 50;

        const result = await client.getPage<Order>('/orders', page, limit, queryParams, 'v2');
        return result;
      },
    },

    bigcommerce_get_order: {
      description: 'Get a single order by ID with full details (products, shipping addresses, coupons)',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number }) => {
        const order = await client.get<Order>(`/orders/${params.order_id}`, 'v2');
        return order;
      },
    },

    bigcommerce_create_order: {
      description: 'Create a new order (manual order entry)',
      parameters: {
        type: 'object' as const,
        properties: {
          customer_id: { type: 'number', description: 'Customer ID', required: true },
          status_id: { type: 'number', description: 'Order status ID (default: 1 for Pending)', required: true },
          billing_address: {
            type: 'object',
            description: 'Billing address object',
            required: true,
            properties: {
              first_name: { type: 'string' },
              last_name: { type: 'string' },
              street_1: { type: 'string' },
              city: { type: 'string' },
              state: { type: 'string' },
              zip: { type: 'string' },
              country: { type: 'string' },
              country_iso2: { type: 'string' },
              email: { type: 'string' },
            },
          },
          products: {
            type: 'array',
            description: 'Array of product line items',
            required: true,
            items: {
              type: 'object',
              properties: {
                product_id: { type: 'number' },
                quantity: { type: 'number' },
                price_inc_tax: { type: 'number' },
                price_ex_tax: { type: 'number' },
              },
            },
          },
        },
        required: ['customer_id', 'status_id', 'billing_address', 'products'],
      },
      handler: async (params: Partial<Order>) => {
        const order = await client.post<Order>('/orders', params, 'v2');
        return order;
      },
    },

    bigcommerce_update_order: {
      description: 'Update an existing order (status, customer message, etc.)',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          status_id: { type: 'number', description: 'New status ID' },
          customer_message: { type: 'string', description: 'Customer message' },
          staff_notes: { type: 'string', description: 'Staff notes (internal)' },
          is_deleted: { type: 'boolean', description: 'Mark as deleted' },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number; [key: string]: unknown }) => {
        const { order_id, ...updateData } = params;
        const order = await client.put<Order>(`/orders/${order_id}`, updateData, 'v2');
        return order;
      },
    },

    bigcommerce_delete_order: {
      description: 'Delete an order (or all orders matching criteria)',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID to delete (omit to delete by filter)' },
          status_id: { type: 'number', description: 'Delete all orders with this status' },
        },
      },
      handler: async (params: { order_id?: number; status_id?: number }) => {
        if (params.order_id) {
          await client.delete(`/orders/${params.order_id}`, 'v2');
          return { success: true, message: `Order ${params.order_id} deleted` };
        } else if (params.status_id) {
          await client.delete(`/orders?status_id=${params.status_id}`, 'v2');
          return { success: true, message: `All orders with status ${params.status_id} deleted` };
        }
        throw new Error('Must provide either order_id or status_id');
      },
    },

    // Order Products
    bigcommerce_list_order_products: {
      description: 'List all products in an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number }) => {
        const products = await client.get<OrderProduct[]>(`/orders/${params.order_id}/products`, 'v2');
        return products;
      },
    },

    bigcommerce_get_order_product: {
      description: 'Get a specific product from an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          product_id: { type: 'number', description: 'Order product ID', required: true },
        },
        required: ['order_id', 'product_id'],
      },
      handler: async (params: { order_id: number; product_id: number }) => {
        const product = await client.get<OrderProduct>(`/orders/${params.order_id}/products/${params.product_id}`, 'v2');
        return product;
      },
    },

    // Order Shipping Addresses
    bigcommerce_list_order_shipping_addresses: {
      description: 'List all shipping addresses for an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number }) => {
        const addresses = await client.get<ShippingAddress[]>(`/orders/${params.order_id}/shipping_addresses`, 'v2');
        return addresses;
      },
    },

    bigcommerce_get_order_shipping_address: {
      description: 'Get a specific shipping address from an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          shipping_address_id: { type: 'number', description: 'Shipping address ID', required: true },
        },
        required: ['order_id', 'shipping_address_id'],
      },
      handler: async (params: { order_id: number; shipping_address_id: number }) => {
        const address = await client.get<ShippingAddress>(`/orders/${params.order_id}/shipping_addresses/${params.shipping_address_id}`, 'v2');
        return address;
      },
    },

    bigcommerce_update_order_shipping_address: {
      description: 'Update a shipping address on an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          shipping_address_id: { type: 'number', description: 'Shipping address ID', required: true },
          first_name: { type: 'string', description: 'First name' },
          last_name: { type: 'string', description: 'Last name' },
          company: { type: 'string', description: 'Company' },
          street_1: { type: 'string', description: 'Street address line 1' },
          street_2: { type: 'string', description: 'Street address line 2' },
          city: { type: 'string', description: 'City' },
          state: { type: 'string', description: 'State/province' },
          zip: { type: 'string', description: 'Postal code' },
          country: { type: 'string', description: 'Country' },
          phone: { type: 'string', description: 'Phone number' },
        },
        required: ['order_id', 'shipping_address_id'],
      },
      handler: async (params: { order_id: number; shipping_address_id: number; [key: string]: unknown }) => {
        const { order_id, shipping_address_id, ...updateData } = params;
        const address = await client.put<ShippingAddress>(`/orders/${order_id}/shipping_addresses/${shipping_address_id}`, updateData, 'v2');
        return address;
      },
    },

    // Order Shipments
    bigcommerce_list_order_shipments: {
      description: 'List all shipments for an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number }) => {
        const result = await client.get<{ data: unknown[] }>(`/orders/${params.order_id}/shipments`);
        return result.data;
      },
    },

    bigcommerce_create_order_shipment: {
      description: 'Create a shipment for an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          tracking_number: { type: 'string', description: 'Tracking number', required: true },
          shipping_provider: { type: 'string', description: 'Shipping carrier (e.g., USPS, FedEx, UPS)' },
          items: {
            type: 'array',
            description: 'Array of order product IDs and quantities to ship',
            items: {
              type: 'object',
              properties: {
                order_product_id: { type: 'number' },
                quantity: { type: 'number' },
              },
            },
            required: true,
          },
        },
        required: ['order_id', 'tracking_number', 'items'],
      },
      handler: async (params: { order_id: number; [key: string]: unknown }) => {
        const { order_id, ...shipmentData } = params;
        const result = await client.post<{ data: unknown }>(`/orders/${order_id}/shipments`, shipmentData);
        return result.data;
      },
    },

    bigcommerce_update_order_shipment: {
      description: 'Update a shipment (tracking number, etc.)',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          shipment_id: { type: 'number', description: 'Shipment ID', required: true },
          tracking_number: { type: 'string', description: 'Tracking number' },
          shipping_provider: { type: 'string', description: 'Shipping carrier' },
        },
        required: ['order_id', 'shipment_id'],
      },
      handler: async (params: { order_id: number; shipment_id: number; [key: string]: unknown }) => {
        const { order_id, shipment_id, ...updateData } = params;
        const result = await client.put<{ data: unknown }>(`/orders/${order_id}/shipments/${shipment_id}`, updateData);
        return result.data;
      },
    },

    bigcommerce_delete_order_shipment: {
      description: 'Delete a shipment from an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          shipment_id: { type: 'number', description: 'Shipment ID', required: true },
        },
        required: ['order_id', 'shipment_id'],
      },
      handler: async (params: { order_id: number; shipment_id: number }) => {
        await client.delete(`/orders/${params.order_id}/shipments/${params.shipment_id}`);
        return { success: true, message: `Shipment ${params.shipment_id} deleted` };
      },
    },

    // Order Coupons
    bigcommerce_list_order_coupons: {
      description: 'List all coupons applied to an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
        },
        required: ['order_id'],
      },
      handler: async (params: { order_id: number }) => {
        const coupons = await client.get<unknown[]>(`/orders/${params.order_id}/coupons`, 'v2');
        return coupons;
      },
    },

    // Order Refunds
    bigcommerce_create_order_refund: {
      description: 'Create a refund for an order',
      parameters: {
        type: 'object' as const,
        properties: {
          order_id: { type: 'number', description: 'Order ID', required: true },
          items: {
            type: 'array',
            description: 'Items to refund',
            items: {
              type: 'object',
              properties: {
                item_type: { type: 'string', enum: ['PRODUCT', 'GIFT_WRAPPING', 'SHIPPING', 'HANDLING', 'TAX'] },
                item_id: { type: 'number' },
                quantity: { type: 'number' },
                reason: { type: 'string' },
              },
            },
            required: true,
          },
          payments: {
            type: 'array',
            description: 'Payment methods for refund',
            items: {
              type: 'object',
              properties: {
                provider_id: { type: 'string' },
                amount: { type: 'number' },
                offline: { type: 'boolean' },
              },
            },
          },
        },
        required: ['order_id', 'items'],
      },
      handler: async (params: { order_id: number; [key: string]: unknown }) => {
        const { order_id, ...refundData } = params;
        const result = await client.post<{ data: unknown }>(`/orders/${order_id}/payment_actions/refund_quotes`, refundData);
        return result.data;
      },
    },

    bigcommerce_get_order_count: {
      description: 'Get total count of orders (optionally filtered by status)',
      parameters: {
        type: 'object' as const,
        properties: {
          status_id: { type: 'number', description: 'Filter by status ID' },
        },
      },
      handler: async (params: { status_id?: number }) => {
        const queryParams = params.status_id ? { status_id: params.status_id } : {};
        const result = await client.get<{ count: number }>('/orders/count', 'v2');
        return result;
      },
    },
  };
}
