/**
 * HubSpot Contacts Tools
 * Tools for managing contacts in HubSpot CRM
 */

import type { HubSpotClient } from '../clients/hubspot.js';
import type { ContactProperties } from '../types/index.js';

export function getTools(client: HubSpotClient) {
  return [
    {
      name: 'hubspot_list_contacts',
      description: 'List contacts with pagination. Returns up to 100 contacts per request.',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of contacts to return (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor from previous response',
          },
          properties: {
            type: 'array',
            items: { type: 'string' },
            description: 'Specific properties to retrieve (e.g., ["email", "firstname", "lastname"])',
          },
        },
      },
      handler: async (args: any) => {
        const response = await client.listObjects<ContactProperties>('contacts', {
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
          properties: args.properties,
        });

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  total: response.results.length,
                  contacts: response.results,
                  nextCursor: response.paging?.next?.after,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_get_contact',
      description: 'Get a single contact by ID with all details',
      inputSchema: {
        type: 'object',
        properties: {
          contactId: {
            type: 'string',
            description: 'HubSpot contact ID',
          },
          properties: {
            type: 'array',
            items: { type: 'string' },
            description: 'Specific properties to retrieve',
          },
          associations: {
            type: 'array',
            items: { type: 'string' },
            description: 'Associated object types to include (e.g., ["companies", "deals"])',
          },
        },
        required: ['contactId'],
      },
      handler: async (args: any) => {
        const contact = await client.getObject<ContactProperties>(
          'contacts',
          args.contactId,
          args.properties,
          args.associations
        );

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(contact, null, 2),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_create_contact',
      description: 'Create a new contact in HubSpot CRM',
      inputSchema: {
        type: 'object',
        properties: {
          email: {
            type: 'string',
            description: 'Contact email address (required for most contacts)',
          },
          firstname: {
            type: 'string',
            description: 'First name',
          },
          lastname: {
            type: 'string',
            description: 'Last name',
          },
          phone: {
            type: 'string',
            description: 'Phone number',
          },
          company: {
            type: 'string',
            description: 'Company name',
          },
          jobtitle: {
            type: 'string',
            description: 'Job title',
          },
          lifecyclestage: {
            type: 'string',
            description: 'Lifecycle stage (e.g., "lead", "opportunity", "customer")',
          },
          additionalProperties: {
            type: 'object',
            description: 'Additional custom properties as key-value pairs',
          },
        },
      },
      handler: async (args: any) => {
        const properties: ContactProperties = {
          email: args.email,
          firstname: args.firstname,
          lastname: args.lastname,
          phone: args.phone,
          company: args.company,
          jobtitle: args.jobtitle,
          lifecyclestage: args.lifecyclestage,
          ...(args.additionalProperties || {}),
        };

        // Remove undefined values
        Object.keys(properties).forEach(
          (key) => properties[key] === undefined && delete properties[key]
        );

        const contact = await client.createObject<ContactProperties>('contacts', properties);

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  success: true,
                  contactId: contact.id,
                  contact,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_update_contact',
      description: 'Update an existing contact',
      inputSchema: {
        type: 'object',
        properties: {
          contactId: {
            type: 'string',
            description: 'HubSpot contact ID',
          },
          email: {
            type: 'string',
            description: 'Updated email address',
          },
          firstname: {
            type: 'string',
            description: 'Updated first name',
          },
          lastname: {
            type: 'string',
            description: 'Updated last name',
          },
          phone: {
            type: 'string',
            description: 'Updated phone number',
          },
          additionalProperties: {
            type: 'object',
            description: 'Additional properties to update as key-value pairs',
          },
        },
        required: ['contactId'],
      },
      handler: async (args: any) => {
        const properties: Partial<ContactProperties> = {
          email: args.email,
          firstname: args.firstname,
          lastname: args.lastname,
          phone: args.phone,
          ...(args.additionalProperties || {}),
        };

        // Remove undefined values
        Object.keys(properties).forEach(
          (key) => properties[key] === undefined && delete properties[key]
        );

        const contact = await client.updateObject<ContactProperties>(
          'contacts',
          args.contactId,
          properties
        );

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  success: true,
                  contact,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_delete_contact',
      description: 'Archive (soft delete) a contact',
      inputSchema: {
        type: 'object',
        properties: {
          contactId: {
            type: 'string',
            description: 'HubSpot contact ID to archive',
          },
        },
        required: ['contactId'],
      },
      handler: async (args: any) => {
        await client.archiveObject('contacts', args.contactId);

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  success: true,
                  message: `Contact ${args.contactId} archived successfully`,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_search_contacts',
      description: 'Search contacts with filters and sorting. Supports complex queries.',
      inputSchema: {
        type: 'object',
        properties: {
          filters: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                propertyName: { type: 'string' },
                operator: { type: 'string', enum: ['EQ', 'NEQ', 'LT', 'LTE', 'GT', 'GTE', 'CONTAINS_TOKEN', 'HAS_PROPERTY'] },
                value: { type: 'string' },
              },
              required: ['propertyName', 'operator'],
            },
            description: 'Array of filters to apply',
          },
          query: {
            type: 'string',
            description: 'Free text search query',
          },
          sorts: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                propertyName: { type: 'string' },
                direction: { type: 'string', enum: ['ASCENDING', 'DESCENDING'] },
              },
            },
            description: 'Sort criteria',
          },
          properties: {
            type: 'array',
            items: { type: 'string' },
            description: 'Properties to retrieve',
          },
          limit: {
            type: 'number',
            description: 'Maximum results (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
      handler: async (args: any) => {
        const searchRequest: any = {
          filterGroups: args.filters
            ? [{ filters: args.filters }]
            : undefined,
          query: args.query,
          sorts: args.sorts,
          properties: args.properties,
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
        };

        const response = await client.searchObjects<ContactProperties>('contacts', searchRequest);

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  total: response.total,
                  results: response.results,
                  nextCursor: response.paging?.next?.after,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_batch_create_contacts',
      description: 'Create multiple contacts in a single batch request (up to 100)',
      inputSchema: {
        type: 'object',
        properties: {
          contacts: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                email: { type: 'string' },
                firstname: { type: 'string' },
                lastname: { type: 'string' },
                phone: { type: 'string' },
                company: { type: 'string' },
              },
            },
            description: 'Array of contact objects to create',
          },
        },
        required: ['contacts'],
      },
      handler: async (args: any) => {
        const inputs = args.contacts.map((c: any) => ({ properties: c }));
        const response = await client.batchCreateObjects<ContactProperties>('contacts', { inputs });

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  success: true,
                  created: response.results.length,
                  contacts: response.results,
                  errors: response.errors,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },

    {
      name: 'hubspot_batch_update_contacts',
      description: 'Update multiple contacts in a single batch request (up to 100)',
      inputSchema: {
        type: 'object',
        properties: {
          updates: {
            type: 'array',
            items: {
              type: 'object',
              properties: {
                id: { type: 'string', description: 'Contact ID' },
                properties: { type: 'object', description: 'Properties to update' },
              },
              required: ['id', 'properties'],
            },
            description: 'Array of contact updates',
          },
        },
        required: ['updates'],
      },
      handler: async (args: any) => {
        const response = await client.batchUpdateObjects<ContactProperties>('contacts', {
          inputs: args.updates,
        });

        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(
                {
                  success: true,
                  updated: response.results.length,
                  contacts: response.results,
                  errors: response.errors,
                },
                null,
                2
              ),
            },
          ],
        };
      },
    },
  ];
}
