/**
 * SOQL and SOSL query tools
 */

import type { SalesforceClient } from '../clients/salesforce.js';
import type { SObject } from '../types/index.js';

export function getTools(client: SalesforceClient) {
  return [
    {
      name: 'sf_run_soql_query',
      description: 'Execute a raw SOQL query. Returns up to 2000 records (use pagination for more).',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'The SOQL query to execute (e.g., "SELECT Id, Name FROM Account WHERE Industry = \'Technology\'")',
          },
        },
        required: ['query'],
      },
      handler: async (args: { query: string }) => {
        const result = await client.query<SObject>(args.query);
        return {
          totalSize: result.totalSize,
          done: result.done,
          records: result.records,
          nextRecordsUrl: result.nextRecordsUrl,
        };
      },
    },

    {
      name: 'sf_run_soql_query_all',
      description: 'Execute a SOQL query and retrieve ALL records (handles pagination automatically). Warning: Can return large result sets.',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'The SOQL query to execute',
          },
        },
        required: ['query'],
      },
      handler: async (args: { query: string }) => {
        const allRecords = await client.queryAll<SObject>(args.query);
        return {
          totalSize: allRecords.length,
          records: allRecords,
        };
      },
    },

    {
      name: 'sf_run_sosl_search',
      description: 'Execute a SOSL (Salesforce Object Search Language) search across multiple objects',
      inputSchema: {
        type: 'object',
        properties: {
          searchQuery: {
            type: 'string',
            description: 'The SOSL search query (e.g., "FIND {John} IN NAME FIELDS RETURNING Account(Name), Contact(FirstName, LastName)")',
          },
        },
        required: ['searchQuery'],
      },
      handler: async (args: { searchQuery: string }) => {
        const results = await client.search<SObject>(args.searchQuery);
        return {
          totalSize: results.length,
          records: results,
        };
      },
    },

    {
      name: 'sf_build_soql_query',
      description: 'Build a SOQL query using a structured format (helper tool)',
      inputSchema: {
        type: 'object',
        properties: {
          select: {
            type: 'array',
            description: 'Fields to select (e.g., ["Id", "Name", "Email"])',
            items: { type: 'string' },
          },
          from: {
            type: 'string',
            description: 'Object to query (e.g., "Account", "Contact")',
          },
          where: {
            type: 'string',
            description: 'WHERE clause (e.g., "Industry = \'Technology\' AND AnnualRevenue > 1000000")',
          },
          orderBy: {
            type: 'string',
            description: 'ORDER BY clause (e.g., "Name ASC", "CreatedDate DESC")',
          },
          limit: {
            type: 'number',
            description: 'LIMIT clause (maximum number of records)',
          },
          offset: {
            type: 'number',
            description: 'OFFSET clause (number of records to skip)',
          },
        },
        required: ['select', 'from'],
      },
      handler: async (args: {
        select: string[];
        from: string;
        where?: string;
        orderBy?: string;
        limit?: number;
        offset?: number;
      }) => {
        const soql = client.buildSOQL(args);
        return {
          query: soql,
          hint: 'Use sf_run_soql_query to execute this query',
        };
      },
    },

    {
      name: 'sf_explain_soql_query',
      description: 'Get the query plan for a SOQL query (analyze performance)',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'The SOQL query to explain',
          },
        },
        required: ['query'],
      },
      handler: async (args: { query: string }) => {
        // Use the Query Plan endpoint
        const response = await client['client'].get('/query', {
          params: {
            q: args.query,
            explain: true,
          },
        });
        return response.data;
      },
    },

    {
      name: 'sf_count_records',
      description: 'Count records matching a condition using COUNT() aggregate',
      inputSchema: {
        type: 'object',
        properties: {
          objectName: {
            type: 'string',
            description: 'Object to count (e.g., "Account", "Contact")',
          },
          whereClause: {
            type: 'string',
            description: 'Optional WHERE clause for filtering',
          },
        },
        required: ['objectName'],
      },
      handler: async (args: { objectName: string; whereClause?: string }) => {
        const soql = `SELECT COUNT() FROM ${args.objectName}${args.whereClause ? ` WHERE ${args.whereClause}` : ''}`;
        const result = await client.query(soql);
        return {
          count: result.totalSize,
          object: args.objectName,
        };
      },
    },

    {
      name: 'sf_aggregate_query',
      description: 'Run aggregate functions (COUNT, SUM, AVG, MAX, MIN) on fields',
      inputSchema: {
        type: 'object',
        properties: {
          objectName: {
            type: 'string',
            description: 'Object to query (e.g., "Opportunity")',
          },
          aggregates: {
            type: 'array',
            description: 'Aggregate functions (e.g., ["COUNT(Id)", "SUM(Amount)", "AVG(Amount)"])',
            items: { type: 'string' },
          },
          groupBy: {
            type: 'array',
            description: 'Fields to group by (e.g., ["StageName"])',
            items: { type: 'string' },
          },
          whereClause: {
            type: 'string',
            description: 'Optional WHERE clause for filtering',
          },
          orderBy: {
            type: 'string',
            description: 'ORDER BY clause (e.g., "SUM(Amount) DESC")',
          },
          limit: {
            type: 'number',
            description: 'LIMIT clause',
          },
        },
        required: ['objectName', 'aggregates'],
      },
      handler: async (args: {
        objectName: string;
        aggregates: string[];
        groupBy?: string[];
        whereClause?: string;
        orderBy?: string;
        limit?: number;
      }) => {
        let soql = `SELECT ${args.aggregates.join(', ')}`;
        
        if (args.groupBy && args.groupBy.length > 0) {
          soql += `, ${args.groupBy.join(', ')}`;
        }
        
        soql += ` FROM ${args.objectName}`;
        
        if (args.whereClause) {
          soql += ` WHERE ${args.whereClause}`;
        }
        
        if (args.groupBy && args.groupBy.length > 0) {
          soql += ` GROUP BY ${args.groupBy.join(', ')}`;
        }
        
        if (args.orderBy) {
          soql += ` ORDER BY ${args.orderBy}`;
        }
        
        if (args.limit) {
          soql += ` LIMIT ${args.limit}`;
        }

        const result = await client.query(soql);
        return {
          query: soql,
          records: result.records,
        };
      },
    },
  ];
}
