import { QuickBooksClient } from '../clients/quickbooks.js';
import type { Purchase, PurchaseOrder } from '../types/index.js';

export function getTools(client: QuickBooksClient) {
  return [
    {
      name: 'qbo_list_purchases',
      description: 'List purchases 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)',
          },
          vendorId: {
            type: 'string',
            description: 'Filter by vendor ID',
          },
          accountId: {
            type: 'string',
            description: 'Filter by account ID',
          },
        },
      },
      handler: async (args: any) => {
        const { startPosition = 1, maxResults = 100, vendorId, accountId } = args;
        
        let query = 'SELECT * FROM Purchase';
        const conditions: string[] = [];
        
        if (vendorId) conditions.push(`EntityRef = '${vendorId}'`);
        if (accountId) conditions.push(`AccountRef = '${accountId}'`);
        
        if (conditions.length > 0) {
          query += ' WHERE ' + conditions.join(' AND ');
        }
        
        return await client.query<Purchase>(query, { startPosition, maxResults });
      },
    },
    {
      name: 'qbo_get_purchase',
      description: 'Get a specific purchase by ID',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Purchase ID',
          },
        },
        required: ['id'],
      },
      handler: async (args: any) => {
        return await client.read<Purchase>('Purchase', args.id);
      },
    },
    {
      name: 'qbo_create_purchase',
      description: 'Create a new purchase (expense, check, or credit card)',
      inputSchema: {
        type: 'object',
        properties: {
          accountId: {
            type: 'string',
            description: 'Payment account ID (bank or credit card)',
          },
          paymentType: {
            type: 'string',
            description: 'Payment type: Cash, Check, CreditCard',
          },
          vendorId: {
            type: 'string',
            description: 'Vendor reference ID (optional)',
          },
          lines: {
            type: 'array',
            description: 'Purchase line items',
            items: {
              type: 'object',
              properties: {
                amount: { type: 'number' },
                description: { type: 'string' },
                accountId: { type: 'string' },
                itemId: { type: 'string' },
              },
            },
          },
          txnDate: {
            type: 'string',
            description: 'Transaction date (YYYY-MM-DD)',
          },
        },
        required: ['accountId', 'paymentType', 'lines'],
      },
      handler: async (args: any) => {
        const purchase: any = {
          AccountRef: { value: args.accountId },
          PaymentType: args.paymentType,
          Line: args.lines.map((line: any) => ({
            Amount: line.amount,
            DetailType: line.itemId ? 'ItemBasedExpenseLineDetail' : 'AccountBasedExpenseLineDetail',
            Description: line.description,
            ...(line.itemId
              ? { ItemBasedExpenseLineDetail: { ItemRef: { value: line.itemId } } }
              : { AccountBasedExpenseLineDetail: { AccountRef: { value: line.accountId } } }
            ),
          })),
        };
        
        if (args.vendorId) purchase.EntityRef = { value: args.vendorId };
        if (args.txnDate) purchase.TxnDate = args.txnDate;
        
        return await client.create<Purchase>('Purchase', purchase);
      },
    },
    {
      name: 'qbo_update_purchase',
      description: 'Update an existing purchase (requires SyncToken)',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Purchase ID',
          },
          syncToken: {
            type: 'string',
            description: 'SyncToken from the purchase',
          },
          lines: {
            type: 'array',
            description: 'Updated line items',
          },
        },
        required: ['id', 'syncToken'],
      },
      handler: async (args: any) => {
        const purchase: any = {
          Id: args.id,
          SyncToken: args.syncToken,
        };
        
        if (args.lines) purchase.Line = args.lines;
        
        return await client.update<Purchase>('Purchase', purchase);
      },
    },
    {
      name: 'qbo_delete_purchase',
      description: 'Delete a purchase (requires SyncToken)',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Purchase ID',
          },
          syncToken: {
            type: 'string',
            description: 'SyncToken from the purchase',
          },
        },
        required: ['id', 'syncToken'],
      },
      handler: async (args: any) => {
        return await client.delete('Purchase', args.id, args.syncToken);
      },
    },
    {
      name: 'qbo_list_purchase_orders',
      description: 'List purchase orders 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)',
          },
          vendorId: {
            type: 'string',
            description: 'Filter by vendor ID',
          },
        },
      },
      handler: async (args: any) => {
        const { startPosition = 1, maxResults = 100, vendorId } = args;
        
        let query = 'SELECT * FROM PurchaseOrder';
        if (vendorId) {
          query += ` WHERE VendorRef = '${vendorId}'`;
        }
        
        return await client.query<PurchaseOrder>(query, { startPosition, maxResults });
      },
    },
    {
      name: 'qbo_get_purchase_order',
      description: 'Get a specific purchase order by ID',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Purchase order ID',
          },
        },
        required: ['id'],
      },
      handler: async (args: any) => {
        return await client.read<PurchaseOrder>('PurchaseOrder', args.id);
      },
    },
    {
      name: 'qbo_create_purchase_order',
      description: 'Create a new purchase order',
      inputSchema: {
        type: 'object',
        properties: {
          vendorId: {
            type: 'string',
            description: 'Vendor reference ID',
          },
          lines: {
            type: 'array',
            description: 'Purchase order line items',
            items: {
              type: 'object',
              properties: {
                amount: { type: 'number' },
                description: { type: 'string' },
                itemId: { type: 'string' },
                quantity: { type: 'number' },
              },
            },
          },
          txnDate: {
            type: 'string',
            description: 'Transaction date (YYYY-MM-DD)',
          },
          dueDate: {
            type: 'string',
            description: 'Due date (YYYY-MM-DD)',
          },
        },
        required: ['vendorId', 'lines'],
      },
      handler: async (args: any) => {
        const purchaseOrder: any = {
          VendorRef: { value: args.vendorId },
          Line: args.lines.map((line: any) => ({
            Amount: line.amount,
            DetailType: 'ItemBasedExpenseLineDetail',
            Description: line.description,
            ItemBasedExpenseLineDetail: {
              ItemRef: { value: line.itemId },
              Qty: line.quantity,
            },
          })),
        };
        
        if (args.txnDate) purchaseOrder.TxnDate = args.txnDate;
        // Note: PurchaseOrder doesn't have DueDate in QBO API
        
        return await client.create<PurchaseOrder>('PurchaseOrder', purchaseOrder);
      },
    },
    {
      name: 'qbo_delete_purchase_order',
      description: 'Delete a purchase order (requires SyncToken)',
      inputSchema: {
        type: 'object',
        properties: {
          id: {
            type: 'string',
            description: 'Purchase order ID',
          },
          syncToken: {
            type: 'string',
            description: 'SyncToken from the purchase order',
          },
        },
        required: ['id', 'syncToken'],
      },
      handler: async (args: any) => {
        return await client.delete('PurchaseOrder', args.id, args.syncToken);
      },
    },
  ];
}
