/**
 * MCP Location Tools for GoHighLevel Integration
 * Exposes location/sub-account management capabilities to the MCP server
 */

import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { GHLApiClient } from '../clients/ghl-api-client.js';
import {
  MCPSearchLocationsParams,
  MCPGetLocationParams,
  MCPCreateLocationParams,
  MCPUpdateLocationParams,
  MCPDeleteLocationParams,
  MCPGetLocationTagsParams,
  MCPCreateLocationTagParams,
  MCPGetLocationTagParams,
  MCPUpdateLocationTagParams,
  MCPDeleteLocationTagParams,
  MCPSearchLocationTasksParams,
  MCPGetCustomFieldsParams,
  MCPCreateCustomFieldParams,
  MCPGetCustomFieldParams,
  MCPUpdateCustomFieldParams,
  MCPDeleteCustomFieldParams,
  MCPGetCustomValuesParams,
  MCPCreateCustomValueParams,
  MCPGetCustomValueParams,
  MCPUpdateCustomValueParams,
  MCPDeleteCustomValueParams,
  MCPGetLocationTemplatesParams,
  MCPDeleteLocationTemplateParams,
  MCPGetTimezonesParams,
  GHLLocation,
  GHLLocationDetailed,
  GHLLocationTag,
  GHLLocationCustomField,
  GHLLocationCustomValue
} from '../types/ghl-types.js';

/**
 * Location Tools Class
 * Implements MCP tools for location and sub-account management
 */
export class LocationTools {
  constructor(private ghlClient: GHLApiClient) {}

  /**
   * Get all location tool definitions for MCP server
   */
  getToolDefinitions(): Tool[] {
    return [
      {
        name: 'search_locations',
        description: 'Search for locations/sub-accounts in GoHighLevel with filtering options',
        inputSchema: {
          type: 'object',
          properties: {
            companyId: {
              type: 'string',
              description: 'Company/Agency ID to filter locations'
            },
            skip: {
              type: 'number',
              description: 'Number of results to skip for pagination (default: 0)',
              default: 0
            },
            limit: {
              type: 'number',
              description: 'Maximum number of locations to return (default: 10)',
              default: 10
            },
            order: {
              type: 'string',
              enum: ['asc', 'desc'],
              description: 'Order of results (default: asc)',
              default: 'asc'
            },
            email: {
              type: 'string',
              description: 'Filter by email address',
              format: 'email'
            }
          }
        }
      },
      {
        name: 'get_location',
        description: 'Get detailed information about a specific location/sub-account by ID',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The unique ID of the location to retrieve'
            }
          },
          required: ['locationId']
        }
      },
      {
        name: 'create_location',
        description: 'Create a new sub-account/location in GoHighLevel (Agency Pro plan required)',
        inputSchema: {
          type: 'object',
          properties: {
            name: {
              type: 'string',
              description: 'Name of the sub-account/location'
            },
            companyId: {
              type: 'string',
              description: 'Company/Agency ID'
            },
            phone: {
              type: 'string',
              description: 'Phone number with country code (e.g., +1410039940)'
            },
            address: {
              type: 'string',
              description: 'Business address'
            },
            city: {
              type: 'string',
              description: 'City where business is located'
            },
            state: {
              type: 'string',
              description: 'State where business operates'
            },
            country: {
              type: 'string',
              description: '2-letter country code (e.g., US, CA, GB)'
            },
            postalCode: {
              type: 'string',
              description: 'Postal/ZIP code'
            },
            website: {
              type: 'string',
              description: 'Business website URL'
            },
            timezone: {
              type: 'string',
              description: 'Business timezone (e.g., US/Central)'
            },
            prospectInfo: {
              type: 'object',
              properties: {
                firstName: { type: 'string', description: 'Prospect first name' },
                lastName: { type: 'string', description: 'Prospect last name' },
                email: { type: 'string', format: 'email', description: 'Prospect email' }
              },
              required: ['firstName', 'lastName', 'email'],
              description: 'Prospect information for the location'
            },
            snapshotId: {
              type: 'string',
              description: 'Snapshot ID to load into the location'
            }
          },
          required: ['name', 'companyId']
        }
      },
      {
        name: 'update_location',
        description: 'Update an existing sub-account/location in GoHighLevel',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The unique ID of the location to update'
            },
            name: {
              type: 'string',
              description: 'Updated name of the sub-account/location'
            },
            companyId: {
              type: 'string',
              description: 'Company/Agency ID'
            },
            phone: {
              type: 'string',
              description: 'Updated phone number'
            },
            address: {
              type: 'string',
              description: 'Updated business address'
            },
            city: {
              type: 'string',
              description: 'Updated city'
            },
            state: {
              type: 'string',
              description: 'Updated state'
            },
            country: {
              type: 'string',
              description: 'Updated 2-letter country code'
            },
            postalCode: {
              type: 'string',
              description: 'Updated postal/ZIP code'
            },
            website: {
              type: 'string',
              description: 'Updated website URL'
            },
            timezone: {
              type: 'string',
              description: 'Updated timezone'
            }
          },
          required: ['locationId', 'companyId']
        }
      },
      {
        name: 'delete_location',
        description: 'Delete a sub-account/location from GoHighLevel',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The unique ID of the location to delete'
            },
            deleteTwilioAccount: {
              type: 'boolean',
              description: 'Whether to delete associated Twilio account',
              default: false
            }
          },
          required: ['locationId', 'deleteTwilioAccount']
        }
      },

      // Location Tags Tools
      {
        name: 'get_location_tags',
        description: 'Get all tags for a specific location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID to get tags from'
            }
          },
          required: ['locationId']
        }
      },
      {
        name: 'create_location_tag',
        description: 'Create a new tag for a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID to create tag in'
            },
            name: {
              type: 'string',
              description: 'Name of the tag to create'
            }
          },
          required: ['locationId', 'name']
        }
      },
      {
        name: 'get_location_tag',
        description: 'Get a specific location tag by ID',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            tagId: {
              type: 'string',
              description: 'The tag ID to retrieve'
            }
          },
          required: ['locationId', 'tagId']
        }
      },
      {
        name: 'update_location_tag',
        description: 'Update an existing location tag',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            tagId: {
              type: 'string',
              description: 'The tag ID to update'
            },
            name: {
              type: 'string',
              description: 'Updated name for the tag'
            }
          },
          required: ['locationId', 'tagId', 'name']
        }
      },
      {
        name: 'delete_location_tag',
        description: 'Delete a location tag',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            tagId: {
              type: 'string',
              description: 'The tag ID to delete'
            }
          },
          required: ['locationId', 'tagId']
        }
      },

      // Location Tasks Tools
      {
        name: 'search_location_tasks',
        description: 'Search tasks within a location with advanced filtering',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID to search tasks in'
            },
            contactId: {
              type: 'array',
              items: { type: 'string' },
              description: 'Filter by specific contact IDs'
            },
            completed: {
              type: 'boolean',
              description: 'Filter by completion status'
            },
            assignedTo: {
              type: 'array',
              items: { type: 'string' },
              description: 'Filter by assigned user IDs'
            },
            query: {
              type: 'string',
              description: 'Search query for task content'
            },
            limit: {
              type: 'number',
              description: 'Maximum number of tasks to return (default: 25)',
              default: 25
            },
            skip: {
              type: 'number',
              description: 'Number of tasks to skip for pagination (default: 0)',
              default: 0
            },
            businessId: {
              type: 'string',
              description: 'Business ID filter'
            }
          },
          required: ['locationId']
        }
      },

      // Custom Fields Tools
      {
        name: 'get_location_custom_fields',
        description: 'Get custom fields for a location, optionally filtered by model type',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            model: {
              type: 'string',
              enum: ['contact', 'opportunity', 'all'],
              description: 'Filter by model type (default: all)',
              default: 'all'
            }
          },
          required: ['locationId']
        }
      },
      {
        name: 'create_location_custom_field',
        description: 'Create a new custom field for a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            name: {
              type: 'string',
              description: 'Name of the custom field'
            },
            dataType: {
              type: 'string',
              description: 'Data type of the field (TEXT, NUMBER, DATE, etc.)'
            },
            placeholder: {
              type: 'string',
              description: 'Placeholder text for the field'
            },
            model: {
              type: 'string',
              enum: ['contact', 'opportunity'],
              description: 'Model to create the field for',
              default: 'contact'
            },
            position: {
              type: 'number',
              description: 'Position/order of the field (default: 0)',
              default: 0
            }
          },
          required: ['locationId', 'name', 'dataType']
        }
      },
      {
        name: 'get_location_custom_field',
        description: 'Get a specific custom field by ID',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customFieldId: {
              type: 'string',
              description: 'The custom field ID to retrieve'
            }
          },
          required: ['locationId', 'customFieldId']
        }
      },
      {
        name: 'update_location_custom_field',
        description: 'Update an existing custom field',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customFieldId: {
              type: 'string',
              description: 'The custom field ID to update'
            },
            name: {
              type: 'string',
              description: 'Updated name of the custom field'
            },
            placeholder: {
              type: 'string',
              description: 'Updated placeholder text'
            },
            position: {
              type: 'number',
              description: 'Updated position/order'
            }
          },
          required: ['locationId', 'customFieldId', 'name']
        }
      },
      {
        name: 'delete_location_custom_field',
        description: 'Delete a custom field from a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customFieldId: {
              type: 'string',
              description: 'The custom field ID to delete'
            }
          },
          required: ['locationId', 'customFieldId']
        }
      },

      // Custom Values Tools
      {
        name: 'get_location_custom_values',
        description: 'Get all custom values for a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            }
          },
          required: ['locationId']
        }
      },
      {
        name: 'create_location_custom_value',
        description: 'Create a new custom value for a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            name: {
              type: 'string',
              description: 'Name of the custom value field'
            },
            value: {
              type: 'string',
              description: 'Value to assign'
            }
          },
          required: ['locationId', 'name', 'value']
        }
      },
      {
        name: 'get_location_custom_value',
        description: 'Get a specific custom value by ID',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customValueId: {
              type: 'string',
              description: 'The custom value ID to retrieve'
            }
          },
          required: ['locationId', 'customValueId']
        }
      },
      {
        name: 'update_location_custom_value',
        description: 'Update an existing custom value',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customValueId: {
              type: 'string',
              description: 'The custom value ID to update'
            },
            name: {
              type: 'string',
              description: 'Updated name'
            },
            value: {
              type: 'string',
              description: 'Updated value'
            }
          },
          required: ['locationId', 'customValueId', 'name', 'value']
        }
      },
      {
        name: 'delete_location_custom_value',
        description: 'Delete a custom value from a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            customValueId: {
              type: 'string',
              description: 'The custom value ID to delete'
            }
          },
          required: ['locationId', 'customValueId']
        }
      },

      // Templates Tools
      {
        name: 'get_location_templates',
        description: 'Get SMS/Email templates for a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            originId: {
              type: 'string',
              description: 'Origin ID (required parameter)'
            },
            deleted: {
              type: 'boolean',
              description: 'Include deleted templates (default: false)',
              default: false
            },
            skip: {
              type: 'number',
              description: 'Number to skip for pagination (default: 0)',
              default: 0
            },
            limit: {
              type: 'number',
              description: 'Maximum number to return (default: 25)',
              default: 25
            },
            type: {
              type: 'string',
              enum: ['sms', 'email', 'whatsapp'],
              description: 'Filter by template type'
            }
          },
          required: ['locationId', 'originId']
        }
      },
      {
        name: 'delete_location_template',
        description: 'Delete a template from a location',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'The location ID'
            },
            templateId: {
              type: 'string',
              description: 'The template ID to delete'
            }
          },
          required: ['locationId', 'templateId']
        }
      },

      // Timezones Tool
      {
        name: 'get_timezones',
        description: 'Get available timezones for location configuration',
        inputSchema: {
          type: 'object',
          properties: {
            locationId: {
              type: 'string',
              description: 'Optional location ID'
            }
          }
        }
      }
    ];
  }

  /**
   * Execute location tool based on tool name and arguments
   */
  async executeTool(name: string, args: any): Promise<any> {
    switch (name) {
      // Location Management
      case 'search_locations':
        return this.searchLocations(args as MCPSearchLocationsParams);
      case 'get_location':
        return this.getLocation(args as MCPGetLocationParams);
      case 'create_location':
        return this.createLocation(args as MCPCreateLocationParams);
      case 'update_location':
        return this.updateLocation(args as MCPUpdateLocationParams);
      case 'delete_location':
        return this.deleteLocation(args as MCPDeleteLocationParams);

      // Location Tags
      case 'get_location_tags':
        return this.getLocationTags(args as MCPGetLocationTagsParams);
      case 'create_location_tag':
        return this.createLocationTag(args as MCPCreateLocationTagParams);
      case 'get_location_tag':
        return this.getLocationTag(args as MCPGetLocationTagParams);
      case 'update_location_tag':
        return this.updateLocationTag(args as MCPUpdateLocationTagParams);
      case 'delete_location_tag':
        return this.deleteLocationTag(args as MCPDeleteLocationTagParams);

      // Location Tasks
      case 'search_location_tasks':
        return this.searchLocationTasks(args as MCPSearchLocationTasksParams);

      // Custom Fields
      case 'get_location_custom_fields':
        return this.getLocationCustomFields(args as MCPGetCustomFieldsParams);
      case 'create_location_custom_field':
        return this.createLocationCustomField(args as MCPCreateCustomFieldParams);
      case 'get_location_custom_field':
        return this.getLocationCustomField(args as MCPGetCustomFieldParams);
      case 'update_location_custom_field':
        return this.updateLocationCustomField(args as MCPUpdateCustomFieldParams);
      case 'delete_location_custom_field':
        return this.deleteLocationCustomField(args as MCPDeleteCustomFieldParams);

      // Custom Values
      case 'get_location_custom_values':
        return this.getLocationCustomValues(args as MCPGetCustomValuesParams);
      case 'create_location_custom_value':
        return this.createLocationCustomValue(args as MCPCreateCustomValueParams);
      case 'get_location_custom_value':
        return this.getLocationCustomValue(args as MCPGetCustomValueParams);
      case 'update_location_custom_value':
        return this.updateLocationCustomValue(args as MCPUpdateCustomValueParams);
      case 'delete_location_custom_value':
        return this.deleteLocationCustomValue(args as MCPDeleteCustomValueParams);

      // Templates
      case 'get_location_templates':
        return this.getLocationTemplates(args as MCPGetLocationTemplatesParams);
      case 'delete_location_template':
        return this.deleteLocationTemplate(args as MCPDeleteLocationTemplateParams);

      // Timezones
      case 'get_timezones':
        return this.getTimezones(args as MCPGetTimezonesParams);

      default:
        throw new Error(`Unknown location tool: ${name}`);
    }
  }

  private async searchLocations(params: MCPSearchLocationsParams): Promise<{ success: boolean; locations: GHLLocation[]; message: string }> {
    try {
      const response = await this.ghlClient.searchLocations(params);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const locations = response.data.locations || [];
      return {
        success: true,
        locations,
        message: `Found ${locations.length} locations`
      };
    } catch (error) {
      throw new Error(`Failed to search locations: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocation(params: MCPGetLocationParams): Promise<{ success: boolean; location: GHLLocationDetailed; message: string }> {
    try {
      const response = await this.ghlClient.getLocationById(params.locationId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        location: response.data.location,
        message: 'Location retrieved successfully'
      };
    } catch (error) {
      throw new Error(`Failed to get location: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationTags(params: MCPGetLocationTagsParams): Promise<{ success: boolean; tags: GHLLocationTag[]; message: string }> {
    try {
      const response = await this.ghlClient.getLocationTags(params.locationId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const tags = response.data.tags || [];
      return {
        success: true,
        tags,
        message: `Retrieved ${tags.length} location tags`
      };
    } catch (error) {
      throw new Error(`Failed to get location tags: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async createLocation(params: MCPCreateLocationParams): Promise<{ success: boolean; location: GHLLocationDetailed; message: string }> {
    try {
      const response = await this.ghlClient.createLocation(params);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        location: response.data,
        message: `Location "${params.name}" created successfully`
      };
    } catch (error) {
      throw new Error(`Failed to create location: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async updateLocation(params: MCPUpdateLocationParams): Promise<{ success: boolean; location: GHLLocationDetailed; message: string }> {
    try {
      const { locationId, ...updateData } = params;
      const response = await this.ghlClient.updateLocation(locationId, updateData);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        location: response.data,
        message: 'Location updated successfully'
      };
    } catch (error) {
      throw new Error(`Failed to update location: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async deleteLocation(params: MCPDeleteLocationParams): Promise<{ success: boolean; message: string }> {
    try {
      const response = await this.ghlClient.deleteLocation(params.locationId, params.deleteTwilioAccount);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        message: response.data.message || 'Location deleted successfully'
      };
    } catch (error) {
      throw new Error(`Failed to delete location: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async createLocationTag(params: MCPCreateLocationTagParams): Promise<{ success: boolean; tag: GHLLocationTag; message: string }> {
    try {
      const response = await this.ghlClient.createLocationTag(params.locationId, { name: params.name });
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        tag: response.data.tag,
        message: `Tag "${params.name}" created successfully`
      };
    } catch (error) {
      throw new Error(`Failed to create location tag: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationTag(params: MCPGetLocationTagParams): Promise<{ success: boolean; tag: GHLLocationTag; message: string }> {
    try {
      const response = await this.ghlClient.getLocationTag(params.locationId, params.tagId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        tag: response.data.tag,
        message: 'Location tag retrieved successfully'
      };
    } catch (error) {
      throw new Error(`Failed to get location tag: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async updateLocationTag(params: MCPUpdateLocationTagParams): Promise<{ success: boolean; tag: GHLLocationTag; message: string }> {
    try {
      const response = await this.ghlClient.updateLocationTag(params.locationId, params.tagId, { name: params.name });
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        tag: response.data.tag,
        message: 'Location tag updated successfully'
      };
    } catch (error) {
      throw new Error(`Failed to update location tag: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async deleteLocationTag(params: MCPDeleteLocationTagParams): Promise<{ success: boolean; message: string }> {
    try {
      const response = await this.ghlClient.deleteLocationTag(params.locationId, params.tagId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        message: 'Location tag deleted successfully'
      };
    } catch (error) {
      throw new Error(`Failed to delete location tag: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async searchLocationTasks(params: MCPSearchLocationTasksParams): Promise<{ success: boolean; tasks: any[]; message: string }> {
    try {
      const { locationId, ...searchParams } = params;
      const response = await this.ghlClient.searchLocationTasks(locationId, searchParams);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const tasks = response.data.tasks || [];
      return {
        success: true,
        tasks,
        message: `Found ${tasks.length} tasks`
      };
    } catch (error) {
      throw new Error(`Failed to search location tasks: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationCustomFields(params: MCPGetCustomFieldsParams): Promise<{ success: boolean; customFields: GHLLocationCustomField[]; message: string }> {
    try {
      const response = await this.ghlClient.getLocationCustomFields(params.locationId, params.model);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const customFields = response.data.customFields || [];
      return {
        success: true,
        customFields,
        message: `Retrieved ${customFields.length} custom fields`
      };
    } catch (error) {
      throw new Error(`Failed to get custom fields: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async createLocationCustomField(params: MCPCreateCustomFieldParams): Promise<{ success: boolean; customField: GHLLocationCustomField; message: string }> {
    try {
      const { locationId, ...fieldData } = params;
      const response = await this.ghlClient.createLocationCustomField(locationId, fieldData);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customField: response.data.customField,
        message: `Custom field "${params.name}" created successfully`
      };
    } catch (error) {
      throw new Error(`Failed to create custom field: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationCustomField(params: MCPGetCustomFieldParams): Promise<{ success: boolean; customField: GHLLocationCustomField; message: string }> {
    try {
      const response = await this.ghlClient.getLocationCustomField(params.locationId, params.customFieldId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customField: response.data.customField,
        message: 'Custom field retrieved successfully'
      };
    } catch (error) {
      throw new Error(`Failed to get custom field: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async updateLocationCustomField(params: MCPUpdateCustomFieldParams): Promise<{ success: boolean; customField: GHLLocationCustomField; message: string }> {
    try {
      const { locationId, customFieldId, ...fieldData } = params;
      const response = await this.ghlClient.updateLocationCustomField(locationId, customFieldId, fieldData);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customField: response.data.customField,
        message: 'Custom field updated successfully'
      };
    } catch (error) {
      throw new Error(`Failed to update custom field: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async deleteLocationCustomField(params: MCPDeleteCustomFieldParams): Promise<{ success: boolean; message: string }> {
    try {
      const response = await this.ghlClient.deleteLocationCustomField(params.locationId, params.customFieldId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        message: 'Custom field deleted successfully'
      };
    } catch (error) {
      throw new Error(`Failed to delete custom field: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationCustomValues(params: MCPGetCustomValuesParams): Promise<{ success: boolean; customValues: GHLLocationCustomValue[]; message: string }> {
    try {
      const response = await this.ghlClient.getLocationCustomValues(params.locationId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const customValues = response.data.customValues || [];
      return {
        success: true,
        customValues,
        message: `Retrieved ${customValues.length} custom values`
      };
    } catch (error) {
      throw new Error(`Failed to get custom values: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async createLocationCustomValue(params: MCPCreateCustomValueParams): Promise<{ success: boolean; customValue: GHLLocationCustomValue; message: string }> {
    try {
      const { locationId, ...valueData } = params;
      const response = await this.ghlClient.createLocationCustomValue(locationId, valueData);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customValue: response.data.customValue,
        message: `Custom value "${params.name}" created successfully`
      };
    } catch (error) {
      throw new Error(`Failed to create custom value: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationCustomValue(params: MCPGetCustomValueParams): Promise<{ success: boolean; customValue: GHLLocationCustomValue; message: string }> {
    try {
      const response = await this.ghlClient.getLocationCustomValue(params.locationId, params.customValueId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customValue: response.data.customValue,
        message: 'Custom value retrieved successfully'
      };
    } catch (error) {
      throw new Error(`Failed to get custom value: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async updateLocationCustomValue(params: MCPUpdateCustomValueParams): Promise<{ success: boolean; customValue: GHLLocationCustomValue; message: string }> {
    try {
      const { locationId, customValueId, ...valueData } = params;
      const response = await this.ghlClient.updateLocationCustomValue(locationId, customValueId, valueData);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        customValue: response.data.customValue,
        message: 'Custom value updated successfully'
      };
    } catch (error) {
      throw new Error(`Failed to update custom value: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async deleteLocationCustomValue(params: MCPDeleteCustomValueParams): Promise<{ success: boolean; message: string }> {
    try {
      const response = await this.ghlClient.deleteLocationCustomValue(params.locationId, params.customValueId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        message: 'Custom value deleted successfully'
      };
    } catch (error) {
      throw new Error(`Failed to delete custom value: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getLocationTemplates(params: MCPGetLocationTemplatesParams): Promise<{ success: boolean; templates: any[]; totalCount: number; message: string }> {
    try {
      const { locationId, ...templateParams } = params;
      const response = await this.ghlClient.getLocationTemplates(locationId, templateParams);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const templates = response.data.templates || [];
      const totalCount = response.data.totalCount || templates.length;
      return {
        success: true,
        templates,
        totalCount,
        message: `Retrieved ${templates.length} templates (${totalCount} total)`
      };
    } catch (error) {
      throw new Error(`Failed to get location templates: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async deleteLocationTemplate(params: MCPDeleteLocationTemplateParams): Promise<{ success: boolean; message: string }> {
    try {
      const response = await this.ghlClient.deleteLocationTemplate(params.locationId, params.templateId);
      if (!response.success) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      return {
        success: true,
        message: 'Template deleted successfully'
      };
    } catch (error) {
      throw new Error(`Failed to delete template: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  private async getTimezones(params: MCPGetTimezonesParams): Promise<{ success: boolean; timezones: string[]; message: string }> {
    try {
      const response = await this.ghlClient.getTimezones(params.locationId);
      if (!response.success || !response.data) {
        const errorMsg = response.error?.message || 'Unknown API error';
        throw new Error(`API request failed: ${errorMsg}`);
      }
      const timezones = Array.isArray(response.data) ? response.data : [];
      return {
        success: true,
        timezones,
        message: `Retrieved ${timezones.length} available timezones`
      };
    } catch (error) {
      throw new Error(`Failed to get timezones: ${error instanceof Error ? error.message : String(error)}`);
    }
  }
} 