import { QuickBooksClient } from '../clients/quickbooks.js';
import type { Item } from '../types/index.js';

export function getTools(client: QuickBooksClient) {
  return [
    {
      name: 'qbo_list_items',
      description: 'List all items with optional filters',
      inputSchema: {
        type: 'object',
        properties: {
          startPosition: {
            type: 'number',
            description: 'Starting position (1-indexed, default 1)',
          },
          maxResults: {
            type: 'number',
            description: 'Maximum results to return (max 1000, default 100)',
          },
          type: {
            type: 'string',
            description: 'Filter by type: Inventory, NonInventory, Service, Category, Bundle',
          },
          active: {
            type: 'boolean',
            description: 'Filter by active status',
          },
        },
      },
      handler: async (args: any) => {
        const { startPosition = 1, maxResults = 100, type, active } = args;
        
        let query = 'SELECT * FROM Item';
        const conditions: string[] = [];
        
        if (type) conditions.push(`Type = '${type}'`);
        if (active !== undefined) conditions.push(`Active = ${active}`);
        
        if (conditions.length > 0) {
          query += ' WHERE ' + conditions.join(' AND ');
        }
        
        return await client.query<Item>(query, { startPosition, maxResults });
      },
    },
    {
      name: 'qbo_get_item',
      description: 'Get a specific item by ID',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Item ID',
          },
        },
        required: ['id'],
      },
      handler: async (args: any) => {
        return await client.read<Item>('Item', args.id);
      },
    },
    {
      name: 'qbo_create_item',
      description: 'Create a new item (inventory, non-inventory, service, or bundle)',
      inputSchema: {
        type: 'object',
        properties: {
          name: {
            type: 'string',
            description: 'Item name',
          },
          type: {
            type: 'string',
            description: 'Item type: Inventory, NonInventory, Service, Category, Bundle',
          },
          incomeAccountId: {
            type: 'string',
            description: 'Income account reference ID',
          },
          expenseAccountId: {
            type: 'string',
            description: 'Expense/COGS account reference ID (for Inventory)',
          },
          assetAccountId: {
            type: 'string',
            description: 'Asset account reference ID (for Inventory)',
          },
          unitPrice: {
            type: 'number',
            description: 'Unit price',
          },
          purchaseCost: {
            type: 'number',
            description: 'Purchase cost (for Inventory)',
          },
          qtyOnHand: {
            type: 'number',
            description: 'Quantity on hand (for Inventory)',
          },
          invStartDate: {
            type: 'string',
            description: 'Inventory start date (YYYY-MM-DD) (for Inventory)',
          },
          description: {
            type: 'string',
            description: 'Item description',
          },
          trackQtyOnHand: {
            type: 'boolean',
            description: 'Track quantity on hand (for Inventory)',
          },
        },
        required: ['name', 'type'],
      },
      handler: async (args: any) => {
        const item: any = {
          Name: args.name,
          Type: args.type,
        };
        
        if (args.incomeAccountId) item.IncomeAccountRef = { value: args.incomeAccountId };
        if (args.expenseAccountId) item.ExpenseAccountRef = { value: args.expenseAccountId };
        if (args.assetAccountId) item.AssetAccountRef = { value: args.assetAccountId };
        if (args.unitPrice !== undefined) item.UnitPrice = args.unitPrice;
        if (args.purchaseCost !== undefined) item.PurchaseCost = args.purchaseCost;
        if (args.qtyOnHand !== undefined) item.QtyOnHand = args.qtyOnHand;
        if (args.invStartDate) item.InvStartDate = args.invStartDate;
        if (args.description) item.Description = args.description;
        if (args.trackQtyOnHand !== undefined) item.TrackQtyOnHand = args.trackQtyOnHand;
        
        return await client.create<Item>('Item', item);
      },
    },
    {
      name: 'qbo_update_item',
      description: 'Update an existing item (requires SyncToken)',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Item ID',
          },
          syncToken: {
            type: 'string',
            description: 'SyncToken from the item',
          },
          name: {
            type: 'string',
            description: 'Item name',
          },
          unitPrice: {
            type: 'number',
            description: 'Unit price',
          },
          purchaseCost: {
            type: 'number',
            description: 'Purchase cost',
          },
          description: {
            type: 'string',
            description: 'Item description',
          },
          active: {
            type: 'boolean',
            description: 'Active status',
          },
        },
        required: ['id', 'syncToken'],
      },
      handler: async (args: any) => {
        const item: any = {
          Id: args.id,
          SyncToken: args.syncToken,
        };
        
        if (args.name) item.Name = args.name;
        if (args.unitPrice !== undefined) item.UnitPrice = args.unitPrice;
        if (args.purchaseCost !== undefined) item.PurchaseCost = args.purchaseCost;
        if (args.description) item.Description = args.description;
        if (args.active !== undefined) item.Active = args.active;
        
        return await client.update<Item>('Item', item);
      },
    },
    {
      name: 'qbo_search_items',
      description: 'Search items by name or description',
      inputSchema: {
        type: 'object',
        properties: {
          searchTerm: {
            type: 'string',
            description: 'Search term to match against item name',
          },
          startPosition: {
            type: 'number',
            description: 'Starting position (default 1)',
          },
          maxResults: {
            type: 'number',
            description: 'Maximum results (default 100)',
          },
        },
        required: ['searchTerm'],
      },
      handler: async (args: any) => {
        const { searchTerm, startPosition = 1, maxResults = 100 } = args;
        const query = `SELECT * FROM Item WHERE Name LIKE '%${searchTerm}%'`;
        
        return await client.query<Item>(query, { startPosition, maxResults });
      },
    },
    {
      name: 'qbo_query_items',
      description: 'Run a custom SQL-like query on items',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'SQL-like query (e.g., "SELECT * FROM Item WHERE Type = \'Inventory\'")',
          },
          startPosition: {
            type: 'number',
            description: 'Starting position (default 1)',
          },
          maxResults: {
            type: 'number',
            description: 'Maximum results (default 100)',
          },
        },
        required: ['query'],
      },
      handler: async (args: any) => {
        return await client.query<Item>(args.query, {
          startPosition: args.startPosition || 1,
          maxResults: args.maxResults || 100,
        });
      },
    },
  ];
}
