/**
 * Event management tools
 */

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

export function getTools(client: SalesforceClient) {
  return [
    {
      name: 'sf_list_events',
      description: 'List events with optional filters. Returns up to 200 events by default.',
      inputSchema: {
        type: 'object',
        properties: {
          limit: {
            type: 'number',
            description: 'Maximum number of events 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., "StartDateTime ASC", "CreatedDate DESC")',
            default: 'StartDateTime ASC',
          },
        },
      },
      handler: async (args: {
        limit?: number;
        offset?: number;
        orderBy?: string;
      }) => {
        const soql = client.buildSOQL({
          select: ['Id', 'Subject', 'StartDateTime', 'EndDateTime', 'Location', 'Description', 'IsAllDayEvent', 'IsPrivate', 'Who.Name', 'What.Name', 'Owner.Name', 'CreatedDate'],
          from: 'Event',
          orderBy: args.orderBy || 'StartDateTime ASC',
          limit: args.limit || 200,
          offset: args.offset,
        });

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

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

    {
      name: 'sf_create_event',
      description: 'Create a new event',
      inputSchema: {
        type: 'object',
        properties: {
          subject: {
            type: 'string',
            description: 'Event subject/title (required)',
          },
          startDateTime: {
            type: 'string',
            description: 'Start date and time in ISO 8601 format (required, e.g., "2024-03-15T14:00:00Z")',
          },
          endDateTime: {
            type: 'string',
            description: 'End date and time in ISO 8601 format (required)',
          },
          location: {
            type: 'string',
            description: 'Event location',
          },
          description: {
            type: 'string',
            description: 'Event description',
          },
          whoId: {
            type: 'string',
            description: 'Related Lead or Contact ID',
          },
          whatId: {
            type: 'string',
            description: 'Related Account, Opportunity, or other object ID',
          },
          isAllDayEvent: {
            type: 'boolean',
            description: 'Whether this is an all-day event',
          },
          isPrivate: {
            type: 'boolean',
            description: 'Whether this is a private event',
          },
        },
        required: ['subject', 'startDateTime', 'endDateTime'],
      },
      handler: async (args: {
        subject: string;
        startDateTime: string;
        endDateTime: string;
        location?: string;
        description?: string;
        whoId?: string;
        whatId?: string;
        isAllDayEvent?: boolean;
        isPrivate?: boolean;
      }) => {
        const eventData: Partial<Event> = {
          Subject: args.subject,
          StartDateTime: args.startDateTime,
          EndDateTime: args.endDateTime,
          Location: args.location,
          Description: args.description,
          WhoId: args.whoId as any,
          WhatId: args.whatId as any,
          IsAllDayEvent: args.isAllDayEvent,
          IsPrivate: args.isPrivate,
        };

        const result = await client.createRecord('Event', eventData);
        return result;
      },
    },

    {
      name: 'sf_update_event',
      description: 'Update an existing event',
      inputSchema: {
        type: 'object',
        properties: {
          eventId: {
            type: 'string',
            description: 'The Salesforce ID of the event to update',
          },
          subject: { type: 'string' },
          startDateTime: { type: 'string', description: 'Start date and time in ISO 8601 format' },
          endDateTime: { type: 'string', description: 'End date and time in ISO 8601 format' },
          location: { type: 'string' },
          description: { type: 'string' },
          whoId: { type: 'string' },
          whatId: { type: 'string' },
          isAllDayEvent: { type: 'boolean' },
          isPrivate: { type: 'boolean' },
        },
        required: ['eventId'],
      },
      handler: async (args: {
        eventId: string;
        subject?: string;
        startDateTime?: string;
        endDateTime?: string;
        location?: string;
        description?: string;
        whoId?: string;
        whatId?: string;
        isAllDayEvent?: boolean;
        isPrivate?: boolean;
      }) => {
        const { eventId, ...updates } = args;
        const eventData: Partial<Event> = {
          Subject: updates.subject,
          StartDateTime: updates.startDateTime,
          EndDateTime: updates.endDateTime,
          Location: updates.location,
          Description: updates.description,
          WhoId: updates.whoId as any,
          WhatId: updates.whatId as any,
          IsAllDayEvent: updates.isAllDayEvent,
          IsPrivate: updates.isPrivate,
        };

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

        await client.updateRecord('Event', eventId, eventData);
        return { success: true, id: eventId };
      },
    },

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

    {
      name: 'sf_search_events',
      description: 'Search events using SOQL with flexible criteria',
      inputSchema: {
        type: 'object',
        properties: {
          searchText: {
            type: 'string',
            description: 'Text to search in Subject, Location, and Description fields',
          },
          whereClause: {
            type: 'string',
            description: 'Custom WHERE clause (e.g., "IsAllDayEvent = true")',
          },
          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 = `(Subject LIKE '%${args.searchText}%' OR Location LIKE '%${args.searchText}%' OR Description LIKE '%${args.searchText}%')`;
          where = where ? `${searchCondition} AND (${where})` : searchCondition;
        }

        const soql = client.buildSOQL({
          select: ['Id', 'Subject', 'StartDateTime', 'EndDateTime', 'Location', 'IsAllDayEvent', 'Who.Name', 'What.Name', 'Owner.Name'],
          from: 'Event',
          where,
          orderBy: 'StartDateTime ASC',
          limit: args.limit || 100,
        });

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

    {
      name: 'sf_find_events_by_date_range',
      description: 'Find events within a specific date range',
      inputSchema: {
        type: 'object',
        properties: {
          startDate: {
            type: 'string',
            description: 'Start date in YYYY-MM-DD format (required)',
          },
          endDate: {
            type: 'string',
            description: 'End date in YYYY-MM-DD format (required)',
          },
          limit: {
            type: 'number',
            description: 'Maximum number of results',
            default: 100,
          },
        },
        required: ['startDate', 'endDate'],
      },
      handler: async (args: { startDate: string; endDate: string; limit?: number }) => {
        const soql = client.buildSOQL({
          select: ['Id', 'Subject', 'StartDateTime', 'EndDateTime', 'Location', 'Who.Name', 'What.Name', 'Owner.Name'],
          from: 'Event',
          where: `StartDateTime >= ${args.startDate}T00:00:00Z AND StartDateTime <= ${args.endDate}T23:59:59Z`,
          orderBy: 'StartDateTime ASC',
          limit: args.limit || 100,
        });

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