/**
 * Intercom Contacts Tools
 */

import { z } from 'zod';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import type { IntercomClient } from '../clients/intercom.js';

// Zod schemas
const CreateContactSchema = z.object({
  role: z.enum(['user', 'lead']).optional(),
  external_id: z.string().optional(),
  email: z.string().email().optional(),
  phone: z.string().optional(),
  name: z.string().optional(),
  avatar: z.string().url().optional(),
  signed_up_at: z.number().optional(),
  last_seen_at: z.number().optional(),
  owner_id: z.number().optional(),
  unsubscribed_from_emails: z.boolean().optional(),
  custom_attributes: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
});

const UpdateContactSchema = z.object({
  id: z.string(),
  role: z.enum(['user', 'lead']).optional(),
  external_id: z.string().optional(),
  email: z.string().email().optional(),
  phone: z.string().optional(),
  name: z.string().optional(),
  avatar: z.string().url().optional(),
  signed_up_at: z.number().optional(),
  last_seen_at: z.number().optional(),
  owner_id: z.number().optional(),
  unsubscribed_from_emails: z.boolean().optional(),
  custom_attributes: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),
});

const SearchContactsSchema = z.object({
  query: z.object({
    field: z.string().optional(),
    operator: z.string().optional(),
    value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]).optional(),
  }).optional(),
  pagination: z.object({
    per_page: z.number().max(150).optional(),
    starting_after: z.string().optional(),
  }).optional(),
  sort: z.object({
    field: z.string(),
    order: z.enum(['asc', 'desc']),
  }).optional(),
});

const MergeContactsSchema = z.object({
  from: z.string(),
  into: z.string(),
});

// Tool definitions
export function getTools(client: IntercomClient): Array<{
  definition: Tool;
  handler: (args: Record<string, unknown>) => Promise<unknown>;
}> {
  return [
    {
      definition: {
        name: 'intercom_list_contacts',
        description: 'List all contacts with cursor-based pagination. Returns up to 150 contacts per page.',
        inputSchema: {
          type: 'object',
          properties: {
            per_page: {
              type: 'number',
              description: 'Number of results per page (max 150, default 50)',
              maximum: 150,
            },
            starting_after: {
              type: 'string',
              description: 'Cursor for pagination - ID of the last contact from previous page',
            },
          },
        },
      },
      handler: async (args) => {
        const params = args as { per_page?: number; starting_after?: string };
        return client.listContacts(params);
      },
    },

    {
      definition: {
        name: 'intercom_get_contact',
        description: 'Retrieve a specific contact by their Intercom ID',
        inputSchema: {
          type: 'object',
          properties: {
            id: {
              type: 'string',
              description: 'The Intercom contact ID',
            },
          },
          required: ['id'],
        },
      },
      handler: async (args) => {
        const { id } = args as { id: string };
        return client.getContact(id as any);
      },
    },

    {
      definition: {
        name: 'intercom_create_contact',
        description: 'Create a new contact (user or lead) in Intercom. At least one of email, phone, or external_id is required.',
        inputSchema: {
          type: 'object',
          properties: {
            role: {
              type: 'string',
              enum: ['user', 'lead'],
              description: 'Contact role (user or lead)',
            },
            external_id: {
              type: 'string',
              description: 'Unique external identifier from your system',
            },
            email: {
              type: 'string',
              description: 'Email address',
            },
            phone: {
              type: 'string',
              description: 'Phone number',
            },
            name: {
              type: 'string',
              description: 'Full name',
            },
            avatar: {
              type: 'string',
              description: 'URL to avatar image',
            },
            signed_up_at: {
              type: 'number',
              description: 'Unix timestamp when contact signed up',
            },
            last_seen_at: {
              type: 'number',
              description: 'Unix timestamp when contact was last seen',
            },
            owner_id: {
              type: 'number',
              description: 'Admin ID of the owner',
            },
            unsubscribed_from_emails: {
              type: 'boolean',
              description: 'Whether contact is unsubscribed from emails',
            },
            custom_attributes: {
              type: 'object',
              description: 'Custom attributes object (key-value pairs)',
            },
          },
        },
      },
      handler: async (args) => {
        const data = CreateContactSchema.parse(args);
        return client.createContact(data as any);
      },
    },

    {
      definition: {
        name: 'intercom_update_contact',
        description: 'Update an existing contact by ID. Only provided fields will be updated.',
        inputSchema: {
          type: 'object',
          properties: {
            id: {
              type: 'string',
              description: 'Contact ID',
            },
            role: {
              type: 'string',
              enum: ['user', 'lead'],
              description: 'Contact role',
            },
            external_id: {
              type: 'string',
              description: 'External identifier',
            },
            email: {
              type: 'string',
              description: 'Email address',
            },
            phone: {
              type: 'string',
              description: 'Phone number',
            },
            name: {
              type: 'string',
              description: 'Full name',
            },
            avatar: {
              type: 'string',
              description: 'Avatar URL',
            },
            signed_up_at: {
              type: 'number',
              description: 'Signup timestamp',
            },
            last_seen_at: {
              type: 'number',
              description: 'Last seen timestamp',
            },
            owner_id: {
              type: 'number',
              description: 'Owner admin ID',
            },
            unsubscribed_from_emails: {
              type: 'boolean',
              description: 'Email subscription status',
            },
            custom_attributes: {
              type: 'object',
              description: 'Custom attributes',
            },
          },
          required: ['id'],
        },
      },
      handler: async (args) => {
        const { id, ...data } = UpdateContactSchema.parse(args);
        return client.updateContact(id as any, data as any);
      },
    },

    {
      definition: {
        name: 'intercom_delete_contact',
        description: 'Permanently delete a contact by ID. This action cannot be undone.',
        inputSchema: {
          type: 'object',
          properties: {
            id: {
              type: 'string',
              description: 'Contact ID to delete',
            },
          },
          required: ['id'],
        },
      },
      handler: async (args) => {
        const { id } = args as { id: string };
        return client.deleteContact(id as any);
      },
    },

    {
      definition: {
        name: 'intercom_search_contacts',
        description: 'Search contacts using filters. Supports complex queries with AND/OR operators.',
        inputSchema: {
          type: 'object',
          properties: {
            query: {
              type: 'object',
              description: 'Filter object with field, operator, and value',
              properties: {
                field: { type: 'string' },
                operator: {
                  type: 'string',
                  enum: ['=', '!=', 'IN', 'NIN', '>', '<', '>=', '<=', '~', '!~', '^', '$'],
                },
                value: {
                  description: 'Value to compare against',
                },
              },
            },
            pagination: {
              type: 'object',
              properties: {
                per_page: {
                  type: 'number',
                  maximum: 150,
                  description: 'Results per page (max 150)',
                },
                starting_after: {
                  type: 'string',
                  description: 'Pagination cursor',
                },
              },
            },
            sort: {
              type: 'object',
              properties: {
                field: {
                  type: 'string',
                  description: 'Field to sort by',
                },
                order: {
                  type: 'string',
                  enum: ['asc', 'desc'],
                  description: 'Sort order',
                },
              },
              required: ['field', 'order'],
            },
          },
        },
      },
      handler: async (args) => {
        const data = SearchContactsSchema.parse(args);
        return client.searchContacts(data as any);
      },
    },

    {
      definition: {
        name: 'intercom_scroll_contacts',
        description: 'Scroll through all contacts using scroll API. Better for large datasets than pagination. Provide scroll_param from previous response to get next page.',
        inputSchema: {
          type: 'object',
          properties: {
            scroll_param: {
              type: 'string',
              description: 'Scroll parameter from previous response (omit for first page)',
            },
          },
        },
      },
      handler: async (args) => {
        const { scroll_param } = args as { scroll_param?: string };
        return client.scrollContacts(scroll_param);
      },
    },

    {
      definition: {
        name: 'intercom_merge_contacts',
        description: 'Merge one contact into another. The "from" contact will be deleted and all data moved to "into" contact.',
        inputSchema: {
          type: 'object',
          properties: {
            from: {
              type: 'string',
              description: 'Contact ID to merge from (will be deleted)',
            },
            into: {
              type: 'string',
              description: 'Contact ID to merge into (will receive all data)',
            },
          },
          required: ['from', 'into'],
        },
      },
      handler: async (args) => {
        const { from, into } = MergeContactsSchema.parse(args);
        return client.mergeContacts(from as any, into as any);
      },
    },

    {
      definition: {
        name: 'intercom_archive_contact',
        description: 'Archive a contact. Archived contacts are hidden but can be unarchived later.',
        inputSchema: {
          type: 'object',
          properties: {
            id: {
              type: 'string',
              description: 'Contact ID to archive',
            },
          },
          required: ['id'],
        },
      },
      handler: async (args) => {
        const { id } = args as { id: string };
        return client.archiveContact(id as any);
      },
    },

    {
      definition: {
        name: 'intercom_unarchive_contact',
        description: 'Unarchive a previously archived contact.',
        inputSchema: {
          type: 'object',
          properties: {
            id: {
              type: 'string',
              description: 'Contact ID to unarchive',
            },
          },
          required: ['id'],
        },
      },
      handler: async (args) => {
        const { id } = args as { id: string };
        return client.unarchiveContact(id as any);
      },
    },
  ];
}
