/**
 * Lead management tools
 */

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

export function getTools(client: SalesforceClient) {
  return [
    {
      name: 'sf_list_leads',
      description: 'List leads with optional filters. Returns up to 200 leads by default.',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of leads to return (default: 200)',
            default: 200,
          },
          offset: {
            type: 'number',
            description: 'Number of records to skip (for pagination)',
          },
          orderBy: {
            type: 'string',
            description: 'Field to sort by (e.g., "LastName ASC", "CreatedDate DESC")',
            default: 'CreatedDate DESC',
          },
          status: {
            type: 'string',
            description: 'Filter by lead status (e.g., "Open", "Contacted", "Qualified")',
          },
          rating: {
            type: 'string',
            description: 'Filter by lead rating (e.g., "Hot", "Warm", "Cold")',
          },
          isConverted: {
            type: 'boolean',
            description: 'Filter by conversion status',
          },
        },
      },
      handler: async (args: {
        limit?: number;
        offset?: number;
        orderBy?: string;
        status?: string;
        rating?: string;
        isConverted?: boolean;
      }) => {
        const conditions: string[] = [];
        if (args.status) conditions.push(`Status = '${args.status}'`);
        if (args.rating) conditions.push(`Rating = '${args.rating}'`);
        if (args.isConverted !== undefined) conditions.push(`IsConverted = ${args.isConverted}`);

        const soql = client.buildSOQL({
          select: ['Id', 'FirstName', 'LastName', 'Company', 'Status', 'Email', 'Phone', 'Title', 'Industry', 'Rating', 'LeadSource', 'IsConverted', 'Owner.Name', 'CreatedDate'],
          from: 'Lead',
          where: conditions.length > 0 ? conditions.join(' AND ') : undefined,
          orderBy: args.orderBy || 'CreatedDate DESC',
          limit: args.limit || 200,
          offset: args.offset,
        });

        const result = await client.query<Lead>(soql);
        return {
          totalSize: result.totalSize,
          records: result.records,
          hasMore: !result.done,
        };
      },
    },

    {
      name: 'sf_get_lead',
      description: 'Get detailed information about a specific lead by ID',
      inputSchema: {
        type: 'object',
        properties: {
          leadId: {
            type: 'string',
            description: 'The Salesforce ID of the lead (15 or 18 characters)',
          },
        },
        required: ['leadId'],
      },
      handler: async (args: { leadId: string }) => {
        const lead = await client.getRecord<Lead>('Lead', args.leadId);
        return lead;
      },
    },

    {
      name: 'sf_create_lead',
      description: 'Create a new lead',
      inputSchema: {
        type: 'object',
        properties: {
          lastName: {
            type: 'string',
            description: 'Last name (required)',
          },
          firstName: {
            type: 'string',
            description: 'First name',
          },
          company: {
            type: 'string',
            description: 'Company name (required)',
          },
          status: {
            type: 'string',
            description: 'Lead status (required, e.g., "Open", "Working", "Qualified")',
          },
          email: {
            type: 'string',
            description: 'Email address',
          },
          phone: {
            type: 'string',
            description: 'Phone number',
          },
          mobilePhone: {
            type: 'string',
            description: 'Mobile phone number',
          },
          title: {
            type: 'string',
            description: 'Job title',
          },
          industry: {
            type: 'string',
            description: 'Industry',
          },
          rating: {
            type: 'string',
            description: 'Lead rating (e.g., "Hot", "Warm", "Cold")',
          },
          leadSource: {
            type: 'string',
            description: 'Lead source (e.g., "Web", "Phone", "Partner")',
          },
          street: {
            type: 'string',
            description: 'Street address',
          },
          city: {
            type: 'string',
            description: 'City',
          },
          state: {
            type: 'string',
            description: 'State/province',
          },
          postalCode: {
            type: 'string',
            description: 'Postal code',
          },
          country: {
            type: 'string',
            description: 'Country',
          },
          description: {
            type: 'string',
            description: 'Lead description',
          },
        },
        required: ['lastName', 'company', 'status'],
      },
      handler: async (args: {
        lastName: string;
        company: string;
        status: string;
        firstName?: string;
        email?: string;
        phone?: string;
        mobilePhone?: string;
        title?: string;
        industry?: string;
        rating?: string;
        leadSource?: string;
        street?: string;
        city?: string;
        state?: string;
        postalCode?: string;
        country?: string;
        description?: string;
      }) => {
        const leadData: Partial<Lead> = {
          LastName: args.lastName,
          FirstName: args.firstName,
          Company: args.company,
          Status: args.status,
          Email: args.email,
          Phone: args.phone,
          MobilePhone: args.mobilePhone,
          Title: args.title,
          Industry: args.industry,
          Rating: args.rating,
          LeadSource: args.leadSource,
          Street: args.street,
          City: args.city,
          State: args.state,
          PostalCode: args.postalCode,
          Country: args.country,
          Description: args.description,
        };

        const result = await client.createRecord('Lead', leadData);
        return result;
      },
    },

    {
      name: 'sf_update_lead',
      description: 'Update an existing lead',
      inputSchema: {
        type: 'object',
        properties: {
          leadId: {
            type: 'string',
            description: 'The Salesforce ID of the lead to update',
          },
          lastName: { type: 'string' },
          firstName: { type: 'string' },
          company: { type: 'string' },
          status: { type: 'string' },
          email: { type: 'string' },
          phone: { type: 'string' },
          mobilePhone: { type: 'string' },
          title: { type: 'string' },
          industry: { type: 'string' },
          rating: { type: 'string' },
          leadSource: { type: 'string' },
          street: { type: 'string' },
          city: { type: 'string' },
          state: { type: 'string' },
          postalCode: { type: 'string' },
          country: { type: 'string' },
          description: { type: 'string' },
        },
        required: ['leadId'],
      },
      handler: async (args: {
        leadId: string;
        lastName?: string;
        firstName?: string;
        company?: string;
        status?: string;
        email?: string;
        phone?: string;
        mobilePhone?: string;
        title?: string;
        industry?: string;
        rating?: string;
        leadSource?: string;
        street?: string;
        city?: string;
        state?: string;
        postalCode?: string;
        country?: string;
        description?: string;
      }) => {
        const { leadId, ...updates } = args;
        const leadData: Partial<Lead> = {
          LastName: updates.lastName,
          FirstName: updates.firstName,
          Company: updates.company,
          Status: updates.status,
          Email: updates.email,
          Phone: updates.phone,
          MobilePhone: updates.mobilePhone,
          Title: updates.title,
          Industry: updates.industry,
          Rating: updates.rating,
          LeadSource: updates.leadSource,
          Street: updates.street,
          City: updates.city,
          State: updates.state,
          PostalCode: updates.postalCode,
          Country: updates.country,
          Description: updates.description,
        };

        // Remove undefined values
        Object.keys(leadData).forEach((key) => {
          if (leadData[key as keyof Lead] === undefined) {
            delete leadData[key as keyof Lead];
          }
        });

        await client.updateRecord('Lead', leadId, leadData);
        return { success: true, id: leadId };
      },
    },

    {
      name: 'sf_delete_lead',
      description: 'Delete a lead by ID',
      inputSchema: {
        type: 'object',
        properties: {
          leadId: {
            type: 'string',
            description: 'The Salesforce ID of the lead to delete',
          },
        },
        required: ['leadId'],
      },
      handler: async (args: { leadId: string }) => {
        await client.deleteRecord('Lead', args.leadId);
        return { success: true, id: args.leadId };
      },
    },

    {
      name: 'sf_convert_lead',
      description: 'Convert a lead to an Account, Contact, and optionally an Opportunity',
      inputSchema: {
        type: 'object',
        properties: {
          leadId: {
            type: 'string',
            description: 'The Salesforce ID of the lead to convert',
          },
          convertedStatus: {
            type: 'string',
            description: 'The converted status (must be a valid converted status from your org)',
          },
          accountId: {
            type: 'string',
            description: 'Existing account ID to attach the contact to (optional)',
          },
          createOpportunity: {
            type: 'boolean',
            description: 'Whether to create an opportunity (default: true)',
            default: true,
          },
          opportunityName: {
            type: 'string',
            description: 'Name for the new opportunity (if creating)',
          },
          ownerId: {
            type: 'string',
            description: 'Owner ID for the new records (defaults to lead owner)',
          },
        },
        required: ['leadId', 'convertedStatus'],
      },
      handler: async (args: {
        leadId: string;
        convertedStatus: string;
        accountId?: string;
        createOpportunity?: boolean;
        opportunityName?: string;
        ownerId?: string;
      }) => {
        // Lead conversion uses a special endpoint
        const convertData = {
          leadId: args.leadId,
          convertedStatus: args.convertedStatus,
          accountId: args.accountId,
          doNotCreateOpportunity: !(args.createOpportunity ?? true),
          opportunityName: args.opportunityName,
          ownerId: args.ownerId,
        };

        // Note: The actual API call would be to /services/data/v59.0/sobjects/Lead/{id}/convert
        // For now, we'll use a composite request
        const result = await client.composite({
          compositeRequest: [
            {
              method: 'POST',
              url: `/services/data/v59.0/sobjects/Lead/${args.leadId}/convert`,
              referenceId: 'convertLead',
              body: convertData,
            },
          ],
        });

        return result.compositeResponse[0].body;
      },
    },

    {
      name: 'sf_search_leads',
      description: 'Search leads using SOQL with flexible criteria',
      inputSchema: {
        type: 'object',
        properties: {
          searchText: {
            type: 'string',
            description: 'Text to search in FirstName, LastName, Company, or Email fields',
          },
          whereClause: {
            type: 'string',
            description: 'Custom WHERE clause (e.g., "Rating = \'Hot\' AND IsConverted = false")',
          },
          limit: {
            type: 'number',
            description: 'Maximum number of results',
            default: 100,
          },
        },
      },
      handler: async (args: { searchText?: string; whereClause?: string; limit?: number }) => {
        let where = args.whereClause;
        
        if (args.searchText) {
          const searchCondition = `(FirstName LIKE '%${args.searchText}%' OR LastName LIKE '%${args.searchText}%' OR Company LIKE '%${args.searchText}%' OR Email LIKE '%${args.searchText}%')`;
          where = where ? `${searchCondition} AND (${where})` : searchCondition;
        }

        const soql = client.buildSOQL({
          select: ['Id', 'FirstName', 'LastName', 'Company', 'Status', 'Email', 'Phone', 'Title', 'Rating', 'LeadSource', 'IsConverted'],
          from: 'Lead',
          where,
          orderBy: 'CreatedDate DESC',
          limit: args.limit || 100,
        });

        const result = await client.query<Lead>(soql);
        return result.records;
      },
    },
  ];
}
