/**
 * Contact management tools
 */

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

export function getTools(client: SalesforceClient) {
  return [
    {
      name: 'sf_list_contacts',
      description: 'List contacts with optional filters. Returns up to 200 contacts by default.',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of contacts 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: 'LastName ASC',
          },
          accountId: {
            type: 'string',
            description: 'Filter by account ID',
          },
        },
      },
      handler: async (args: {
        limit?: number;
        offset?: number;
        orderBy?: string;
        accountId?: string;
      }) => {
        const conditions: string[] = [];
        if (args.accountId) conditions.push(`AccountId = '${args.accountId}'`);

        const soql = client.buildSOQL({
          select: ['Id', 'FirstName', 'LastName', 'Email', 'Phone', 'Title', 'Account.Name', 'MailingCity', 'MailingState', 'Owner.Name', 'CreatedDate'],
          from: 'Contact',
          where: conditions.length > 0 ? conditions.join(' AND ') : undefined,
          orderBy: args.orderBy || 'LastName ASC',
          limit: args.limit || 200,
          offset: args.offset,
        });

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

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

    {
      name: 'sf_create_contact',
      description: 'Create a new contact',
      inputSchema: {
        type: 'object',
        properties: {
          lastName: {
            type: 'string',
            description: 'Last name (required)',
          },
          firstName: {
            type: 'string',
            description: 'First name',
          },
          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',
          },
          department: {
            type: 'string',
            description: 'Department',
          },
          accountId: {
            type: 'string',
            description: 'Associated account ID',
          },
          mailingStreet: {
            type: 'string',
            description: 'Mailing street address',
          },
          mailingCity: {
            type: 'string',
            description: 'Mailing city',
          },
          mailingState: {
            type: 'string',
            description: 'Mailing state/province',
          },
          mailingPostalCode: {
            type: 'string',
            description: 'Mailing postal code',
          },
          mailingCountry: {
            type: 'string',
            description: 'Mailing country',
          },
          description: {
            type: 'string',
            description: 'Contact description',
          },
        },
        required: ['lastName'],
      },
      handler: async (args: {
        lastName: string;
        firstName?: string;
        email?: string;
        phone?: string;
        mobilePhone?: string;
        title?: string;
        department?: string;
        accountId?: string;
        mailingStreet?: string;
        mailingCity?: string;
        mailingState?: string;
        mailingPostalCode?: string;
        mailingCountry?: string;
        description?: string;
      }) => {
        const contactData: Partial<Contact> = {
          LastName: args.lastName,
          FirstName: args.firstName,
          Email: args.email,
          Phone: args.phone,
          MobilePhone: args.mobilePhone,
          Title: args.title,
          Department: args.department,
          AccountId: args.accountId as any,
          MailingStreet: args.mailingStreet,
          MailingCity: args.mailingCity,
          MailingState: args.mailingState,
          MailingPostalCode: args.mailingPostalCode,
          MailingCountry: args.mailingCountry,
          Description: args.description,
        };

        const result = await client.createRecord('Contact', contactData);
        return result;
      },
    },

    {
      name: 'sf_update_contact',
      description: 'Update an existing contact',
      inputSchema: {
        type: 'object',
        properties: {
          contactId: {
            type: 'string',
            description: 'The Salesforce ID of the contact to update',
          },
          lastName: {
            type: 'string',
            description: 'Last name',
          },
          firstName: {
            type: 'string',
            description: 'First name',
          },
          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',
          },
          department: {
            type: 'string',
            description: 'Department',
          },
          accountId: {
            type: 'string',
            description: 'Associated account ID',
          },
          mailingStreet: {
            type: 'string',
            description: 'Mailing street address',
          },
          mailingCity: {
            type: 'string',
            description: 'Mailing city',
          },
          mailingState: {
            type: 'string',
            description: 'Mailing state/province',
          },
          mailingPostalCode: {
            type: 'string',
            description: 'Mailing postal code',
          },
          mailingCountry: {
            type: 'string',
            description: 'Mailing country',
          },
          description: {
            type: 'string',
            description: 'Contact description',
          },
        },
        required: ['contactId'],
      },
      handler: async (args: {
        contactId: string;
        lastName?: string;
        firstName?: string;
        email?: string;
        phone?: string;
        mobilePhone?: string;
        title?: string;
        department?: string;
        accountId?: string;
        mailingStreet?: string;
        mailingCity?: string;
        mailingState?: string;
        mailingPostalCode?: string;
        mailingCountry?: string;
        description?: string;
      }) => {
        const { contactId, ...updates } = args;
        const contactData: Partial<Contact> = {
          LastName: updates.lastName,
          FirstName: updates.firstName,
          Email: updates.email,
          Phone: updates.phone,
          MobilePhone: updates.mobilePhone,
          Title: updates.title,
          Department: updates.department,
          AccountId: updates.accountId as any,
          MailingStreet: updates.mailingStreet,
          MailingCity: updates.mailingCity,
          MailingState: updates.mailingState,
          MailingPostalCode: updates.mailingPostalCode,
          MailingCountry: updates.mailingCountry,
          Description: updates.description,
        };

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

        await client.updateRecord('Contact', contactId, contactData);
        return { success: true, id: contactId };
      },
    },

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

    {
      name: 'sf_search_contacts',
      description: 'Search contacts using SOQL with flexible criteria',
      inputSchema: {
        type: 'object',
        properties: {
          searchText: {
            type: 'string',
            description: 'Text to search in FirstName, LastName, or Email fields',
          },
          whereClause: {
            type: 'string',
            description: 'Custom WHERE clause (e.g., "Department = \'Sales\'")',
          },
          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 Email LIKE '%${args.searchText}%')`;
          where = where ? `${searchCondition} AND (${where})` : searchCondition;
        }

        const soql = client.buildSOQL({
          select: ['Id', 'FirstName', 'LastName', 'Email', 'Phone', 'Title', 'Department', 'Account.Name', 'MailingCity', 'MailingState'],
          from: 'Contact',
          where,
          orderBy: 'LastName ASC',
          limit: args.limit || 100,
        });

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

    {
      name: 'sf_find_contacts_by_email',
      description: 'Find contacts by email address (exact or partial match)',
      inputSchema: {
        type: 'object',
        properties: {
          email: {
            type: 'string',
            description: 'Email address to search for',
          },
          exactMatch: {
            type: 'boolean',
            description: 'Whether to require exact match (default: false)',
            default: false,
          },
        },
        required: ['email'],
      },
      handler: async (args: { email: string; exactMatch?: boolean }) => {
        const condition = args.exactMatch
          ? `Email = '${args.email}'`
          : `Email LIKE '%${args.email}%'`;

        const soql = client.buildSOQL({
          select: ['Id', 'FirstName', 'LastName', 'Email', 'Phone', 'Title', 'Account.Name'],
          from: 'Contact',
          where: condition,
          orderBy: 'LastName ASC',
          limit: 50,
        });

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