/**
 * HubSpot Engagements Tools
 * Tools for managing engagements: notes, calls, emails, meetings, tasks
 */

import type { HubSpotClient } from '../clients/hubspot.js';
import type {
  NoteProperties,
  CallProperties,
  EmailEngagementProperties,
  MeetingProperties,
  TaskProperties,
} from '../types/index.js';

export function getTools(client: HubSpotClient) {
  return [
    // Notes
    {
      name: 'hubspot_list_notes',
      description: 'List engagement notes',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of notes to return (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
      handler: async (args: any) => {
        const response = await client.listObjects<NoteProperties>('notes', {
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
        });

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

    {
      name: 'hubspot_get_note',
      description: 'Get a specific note by ID',
      inputSchema: {
        type: 'object',
        properties: {
          noteId: {
            type: 'string',
            description: 'Note ID',
          },
        },
        required: ['noteId'],
      },
      handler: async (args: any) => {
        const note = await client.getObject<NoteProperties>('notes', args.noteId);

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

    {
      name: 'hubspot_create_note',
      description: 'Create a new engagement note',
      inputSchema: {
        type: 'object',
        properties: {
          note_body: {
            type: 'string',
            description: 'Note content/body',
          },
          hs_timestamp: {
            type: 'string',
            description: 'Timestamp (ISO format)',
          },
          hubspot_owner_id: {
            type: 'string',
            description: 'Owner ID',
          },
        },
        required: ['note_body'],
      },
      handler: async (args: any) => {
        const properties: any = {
          hs_note_body: args.note_body,
          hs_timestamp: args.hs_timestamp || new Date().toISOString(),
          hubspot_owner_id: args.hubspot_owner_id,
        };

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

        const note = await client.createObject<NoteProperties>('notes', properties);

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

    {
      name: 'hubspot_update_note',
      description: 'Update an existing note',
      inputSchema: {
        type: 'object',
        properties: {
          noteId: {
            type: 'string',
            description: 'Note ID',
          },
          note_body: {
            type: 'string',
            description: 'Updated note content',
          },
        },
        required: ['noteId'],
      },
      handler: async (args: any) => {
        const properties: any = {};
        if (args.note_body) properties.hs_note_body = args.note_body;

        const note = await client.updateObject<NoteProperties>('notes', args.noteId, properties);

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

    {
      name: 'hubspot_delete_note',
      description: 'Archive a note',
      inputSchema: {
        type: 'object',
        properties: {
          noteId: {
            type: 'string',
            description: 'Note ID to archive',
          },
        },
        required: ['noteId'],
      },
      handler: async (args: any) => {
        await client.archiveObject('notes', args.noteId);

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

    // Calls
    {
      name: 'hubspot_list_calls',
      description: 'List engagement calls',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of calls to return (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
      handler: async (args: any) => {
        const response = await client.listObjects<CallProperties>('calls', {
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
        });

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

    {
      name: 'hubspot_create_call',
      description: 'Create a new call engagement',
      inputSchema: {
        type: 'object',
        properties: {
          title: {
            type: 'string',
            description: 'Call title',
          },
          body: {
            type: 'string',
            description: 'Call notes/description',
          },
          duration: {
            type: 'string',
            description: 'Duration in milliseconds',
          },
          status: {
            type: 'string',
            description: 'Call status (e.g., COMPLETED, SCHEDULED)',
          },
          direction: {
            type: 'string',
            description: 'INBOUND or OUTBOUND',
          },
          hs_timestamp: {
            type: 'string',
            description: 'Timestamp (ISO format)',
          },
        },
      },
      handler: async (args: any) => {
        const properties: any = {
          hs_call_title: args.title,
          hs_call_body: args.body,
          hs_call_duration: args.duration,
          hs_call_status: args.status,
          hs_call_direction: args.direction,
          hs_timestamp: args.hs_timestamp || new Date().toISOString(),
        };

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

        const call = await client.createObject<CallProperties>('calls', properties);

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

    {
      name: 'hubspot_delete_call',
      description: 'Archive a call engagement',
      inputSchema: {
        type: 'object',
        properties: {
          callId: {
            type: 'string',
            description: 'Call ID to archive',
          },
        },
        required: ['callId'],
      },
      handler: async (args: any) => {
        await client.archiveObject('calls', args.callId);

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

    // Meetings
    {
      name: 'hubspot_list_meetings',
      description: 'List engagement meetings',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of meetings to return (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
      handler: async (args: any) => {
        const response = await client.listObjects<MeetingProperties>('meetings', {
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
        });

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

    {
      name: 'hubspot_create_meeting',
      description: 'Create a new meeting engagement',
      inputSchema: {
        type: 'object',
        properties: {
          title: {
            type: 'string',
            description: 'Meeting title',
          },
          body: {
            type: 'string',
            description: 'Meeting notes/description',
          },
          start_time: {
            type: 'string',
            description: 'Start time (ISO format)',
          },
          end_time: {
            type: 'string',
            description: 'End time (ISO format)',
          },
          outcome: {
            type: 'string',
            description: 'Meeting outcome',
          },
        },
      },
      handler: async (args: any) => {
        const properties: any = {
          hs_meeting_title: args.title,
          hs_meeting_body: args.body,
          hs_meeting_start_time: args.start_time,
          hs_meeting_end_time: args.end_time,
          hs_meeting_outcome: args.outcome,
          hs_timestamp: args.start_time || new Date().toISOString(),
        };

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

        const meeting = await client.createObject<MeetingProperties>('meetings', properties);

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

    {
      name: 'hubspot_delete_meeting',
      description: 'Archive a meeting engagement',
      inputSchema: {
        type: 'object',
        properties: {
          meetingId: {
            type: 'string',
            description: 'Meeting ID to archive',
          },
        },
        required: ['meetingId'],
      },
      handler: async (args: any) => {
        await client.archiveObject('meetings', args.meetingId);

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

    // Tasks
    {
      name: 'hubspot_list_tasks',
      description: 'List engagement tasks',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of tasks to return (max 100)',
            default: 10,
          },
          after: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
      handler: async (args: any) => {
        const response = await client.listObjects<TaskProperties>('tasks', {
          limit: Math.min(args.limit || 10, 100),
          after: args.after,
        });

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

    {
      name: 'hubspot_create_task',
      description: 'Create a new task engagement',
      inputSchema: {
        type: 'object',
        properties: {
          subject: {
            type: 'string',
            description: 'Task subject',
          },
          body: {
            type: 'string',
            description: 'Task description',
          },
          status: {
            type: 'string',
            description: 'Task status (e.g., NOT_STARTED, IN_PROGRESS, COMPLETED)',
          },
          priority: {
            type: 'string',
            description: 'Task priority (e.g., LOW, MEDIUM, HIGH)',
          },
          task_type: {
            type: 'string',
            description: 'Task type (e.g., TODO, EMAIL, CALL)',
          },
        },
      },
      handler: async (args: any) => {
        const properties: any = {
          hs_task_subject: args.subject,
          hs_task_body: args.body,
          hs_task_status: args.status,
          hs_task_priority: args.priority,
          hs_task_type: args.task_type,
          hs_timestamp: new Date().toISOString(),
        };

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

        const task = await client.createObject<TaskProperties>('tasks', properties);

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

    {
      name: 'hubspot_update_task',
      description: 'Update an existing task',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: {
            type: 'string',
            description: 'Task ID',
          },
          status: {
            type: 'string',
            description: 'Updated task status',
          },
          priority: {
            type: 'string',
            description: 'Updated priority',
          },
        },
        required: ['taskId'],
      },
      handler: async (args: any) => {
        const properties: any = {};
        if (args.status) properties.hs_task_status = args.status;
        if (args.priority) properties.hs_task_priority = args.priority;

        const task = await client.updateObject<TaskProperties>('tasks', args.taskId, properties);

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

    {
      name: 'hubspot_delete_task',
      description: 'Archive a task engagement',
      inputSchema: {
        type: 'object',
        properties: {
          taskId: {
            type: 'string',
            description: 'Task ID to archive',
          },
        },
        required: ['taskId'],
      },
      handler: async (args: any) => {
        await client.archiveObject('tasks', args.taskId);

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