import { ServiceBubble } from '../../../types/service-bubble-class.js';
import { CredentialType } from '@bubblelab/shared-schemas';
import { HubSpotParamsSchema, HubSpotResultSchema, } from './hubspot.schema.js';
/**
 * HubSpot CRM Service Bubble
 *
 * Comprehensive HubSpot CRM integration for managing contacts, companies,
 * deals, tickets, properties, associations, pipelines, notes, owners,
 * lists, and account information.
 */
export class HubSpotBubble extends ServiceBubble {
    static type = 'service';
    static service = 'hubspot';
    static authType = 'oauth';
    static bubbleName = 'hubspot';
    static schema = HubSpotParamsSchema;
    static resultSchema = HubSpotResultSchema;
    static shortDescription = 'HubSpot CRM integration for contacts, companies, deals, and tickets';
    static longDescription = `
    HubSpot CRM service integration for comprehensive customer relationship management.

    Features:
    - Full CRUD + batch operations for contacts, companies, deals, and tickets
    - Advanced search with filter groups supporting AND/OR logic
    - Property definition management (create, update, delete custom properties)
    - Record associations (link contacts to companies, deals, etc.)
    - Pipeline and stage management for deals and tickets
    - Note creation with record associations
    - Account information retrieval

    Security Features:
    - OAuth 2.0 authentication with HubSpot
    - Scoped access permissions for CRM operations
    - Secure credential handling and validation
  `;
    static alias = 'crm';
    // Note association type IDs (HubSpot-defined)
    static NOTE_ASSOC_TYPES = {
        contacts: 202,
        companies: 190,
        deals: 214,
        tickets: 18,
    };
    constructor(params = {
        operation: 'get_record',
        object_type: 'contacts',
        record_id: '',
    }, context) {
        super(params, context);
    }
    async testCredential() {
        const credential = this.chooseCredential();
        if (!credential) {
            throw new Error('HubSpot credentials are required');
        }
        const response = await fetch('https://api.hubapi.com/crm/v3/objects/contacts?limit=1', {
            headers: {
                Authorization: `Bearer ${credential}`,
            },
        });
        if (!response.ok) {
            const text = await response.text();
            throw new Error(`HubSpot API error (${response.status}): ${text}`);
        }
        return true;
    }
    chooseCredential() {
        const { credentials } = this.params;
        if (!credentials || typeof credentials !== 'object') {
            throw new Error('No HubSpot credentials provided');
        }
        return credentials[CredentialType.HUBSPOT_CRED];
    }
    async makeHubSpotApiRequest(endpoint, method = 'GET', body) {
        const credential = this.chooseCredential();
        if (!credential) {
            throw new Error('HubSpot credentials are required');
        }
        const url = endpoint.startsWith('https://')
            ? endpoint
            : `https://api.hubapi.com${endpoint}`;
        const requestInit = {
            method,
            headers: {
                Authorization: `Bearer ${credential}`,
                'Content-Type': 'application/json',
            },
        };
        if (body && method !== 'GET') {
            requestInit.body = JSON.stringify(body);
        }
        const response = await fetch(url, requestInit);
        if (!response.ok) {
            const errorText = await response.text();
            throw new Error(`HubSpot API error (${response.status}): ${errorText}`);
        }
        // DELETE often returns 204 No Content
        if (response.status === 204) {
            return undefined;
        }
        const contentType = response.headers.get('content-type');
        if (contentType && contentType.includes('application/json')) {
            return await response.json();
        }
        return await response.text();
    }
    async performAction(context) {
        void context;
        const { operation } = this.params;
        try {
            const result = await (async () => {
                const p = this.params;
                switch (operation) {
                    // Record CRUD
                    case 'create_record':
                        return this.createRecord(p);
                    case 'get_record':
                        return this.getRecord(p);
                    case 'update_record':
                        return this.updateRecord(p);
                    case 'delete_record':
                        return this.deleteRecord(p);
                    case 'search_records':
                        return this.searchRecords(p);
                    case 'batch_create_records':
                        return this.batchCreateRecords(p);
                    case 'batch_update_records':
                        return this.batchUpdateRecords(p);
                    case 'batch_delete_records':
                        return this.batchDeleteRecords(p);
                    // Properties
                    case 'list_properties':
                        return this.listProperties(p);
                    case 'get_property':
                        return this.getProperty(p);
                    case 'create_property':
                        return this.createProperty(p);
                    case 'update_property':
                        return this.updateProperty(p);
                    case 'delete_property':
                        return this.deleteProperty(p);
                    // Associations
                    case 'list_associations':
                        return this.listAssociations(p);
                    case 'create_association':
                        return this.createAssociation(p);
                    case 'remove_association':
                        return this.removeAssociation(p);
                    // Pipelines
                    case 'list_pipelines':
                        return this.listPipelines(p);
                    // Notes
                    case 'create_note':
                        return this.createNote(p);
                    // Account
                    case 'get_account_info':
                        return this.getAccountInfo();
                    default:
                        throw new Error(`Unsupported operation: ${operation}`);
                }
            })();
            return result;
        }
        catch (error) {
            return {
                operation,
                success: false,
                error: error instanceof Error ? error.message : 'Unknown error occurred',
            };
        }
    }
    // =====================================================================
    // Record CRUD
    // =====================================================================
    async createRecord(params) {
        const { object_type, properties } = params;
        const r = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}`, 'POST', { properties }));
        return {
            operation: 'create_record',
            success: true,
            record: {
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            },
            error: '',
        };
    }
    async getRecord(params) {
        const { object_type, record_id, properties } = params;
        const qp = new URLSearchParams();
        if (properties && properties.length > 0) {
            qp.set('properties', properties.join(','));
        }
        const qs = qp.toString();
        const r = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/${record_id}${qs ? `?${qs}` : ''}`, 'GET'));
        return {
            operation: 'get_record',
            success: true,
            record: {
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            },
            error: '',
        };
    }
    async updateRecord(params) {
        const { object_type, record_id, properties } = params;
        const r = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/${record_id}`, 'PATCH', { properties }));
        return {
            operation: 'update_record',
            success: true,
            record: {
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            },
            error: '',
        };
    }
    async deleteRecord(params) {
        const { object_type, record_id } = params;
        await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/${record_id}`, 'DELETE');
        return { operation: 'delete_record', success: true, error: '' };
    }
    async searchRecords(params) {
        const { object_type, filter_groups, properties, limit, after } = params;
        const body = {
            filterGroups: filter_groups.map((group) => ({
                filters: group.filters.map((filter) => {
                    const f = {
                        propertyName: filter.propertyName,
                        operator: filter.operator,
                    };
                    if (filter.value !== undefined)
                        f.value = filter.value;
                    if (filter.highValue !== undefined)
                        f.highValue = filter.highValue;
                    if (filter.values !== undefined)
                        f.values = filter.values;
                    return f;
                }),
            })),
            limit: limit || 10,
        };
        if (properties && properties.length > 0)
            body.properties = properties;
        if (after)
            body.after = after;
        const response = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/search`, 'POST', body));
        return {
            operation: 'search_records',
            success: true,
            results: (response.results ?? []).map((r) => ({
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            })),
            total: response.total,
            paging: response.paging,
            error: '',
        };
    }
    async batchCreateRecords(params) {
        const { object_type, records } = params;
        const response = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/batch/create`, 'POST', { inputs: records }));
        return {
            operation: 'batch_create_records',
            success: true,
            results: (response.results ?? []).map((r) => ({
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            })),
            error: '',
        };
    }
    async batchUpdateRecords(params) {
        const { object_type, records } = params;
        const response = (await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/batch/update`, 'POST', { inputs: records }));
        return {
            operation: 'batch_update_records',
            success: true,
            results: (response.results ?? []).map((r) => ({
                id: r.id,
                properties: (r.properties ?? {}),
                createdAt: r.createdAt,
                updatedAt: r.updatedAt,
                archived: r.archived,
            })),
            error: '',
        };
    }
    async batchDeleteRecords(params) {
        const { object_type, record_ids } = params;
        await this.makeHubSpotApiRequest(`/crm/v3/objects/${object_type}/batch/archive`, 'POST', { inputs: record_ids.map((id) => ({ id })) });
        return { operation: 'batch_delete_records', success: true, error: '' };
    }
    // =====================================================================
    // Properties
    // =====================================================================
    async listProperties(params) {
        const { object_type } = params;
        const response = await this.makeHubSpotApiRequest(`/crm/v3/properties/${object_type}`, 'GET');
        const results = response;
        return {
            operation: 'list_properties',
            success: true,
            properties: (results.results ??
                results),
            error: '',
        };
    }
    async getProperty(params) {
        const { object_type, property_name } = params;
        const response = await this.makeHubSpotApiRequest(`/crm/v3/properties/${object_type}/${property_name}`, 'GET');
        return {
            operation: 'get_property',
            success: true,
            property: response,
            error: '',
        };
    }
    async createProperty(params) {
        const { object_type, name, label, type, fieldType, groupName, description, hasUniqueValue, options, calculationFormula, } = params;
        const body = {
            name,
            label,
            type,
            fieldType,
            groupName,
        };
        if (description !== undefined)
            body.description = description;
        if (hasUniqueValue !== undefined)
            body.hasUniqueValue = hasUniqueValue;
        if (options !== undefined)
            body.options = options;
        if (calculationFormula !== undefined)
            body.calculationFormula = calculationFormula;
        const response = await this.makeHubSpotApiRequest(`/crm/v3/properties/${object_type}`, 'POST', body);
        return {
            operation: 'create_property',
            success: true,
            property: response,
            error: '',
        };
    }
    async updateProperty(params) {
        const { object_type, property_name, label, description, groupName, type, fieldType, options, } = params;
        const body = {};
        if (label !== undefined)
            body.label = label;
        if (description !== undefined)
            body.description = description;
        if (groupName !== undefined)
            body.groupName = groupName;
        if (type !== undefined)
            body.type = type;
        if (fieldType !== undefined)
            body.fieldType = fieldType;
        if (options !== undefined)
            body.options = options;
        const response = await this.makeHubSpotApiRequest(`/crm/v3/properties/${object_type}/${property_name}`, 'PATCH', body);
        return {
            operation: 'update_property',
            success: true,
            property: response,
            error: '',
        };
    }
    async deleteProperty(params) {
        const { object_type, property_name } = params;
        await this.makeHubSpotApiRequest(`/crm/v3/properties/${object_type}/${property_name}`, 'DELETE');
        return { operation: 'delete_property', success: true, error: '' };
    }
    // =====================================================================
    // Associations
    // =====================================================================
    async listAssociations(params) {
        const { from_object_type, from_record_id, to_object_type } = params;
        const response = (await this.makeHubSpotApiRequest(`/crm/v4/objects/${from_object_type}/${from_record_id}/associations/${to_object_type}`, 'GET'));
        return {
            operation: 'list_associations',
            success: true,
            associations: (response.results ?? []),
            error: '',
        };
    }
    async createAssociation(params) {
        const { from_object_type, from_record_id, to_object_type, to_record_id } = params;
        await this.makeHubSpotApiRequest(`/crm/v4/objects/${from_object_type}/${from_record_id}/associations/default/${to_object_type}/${to_record_id}`, 'PUT');
        return { operation: 'create_association', success: true, error: '' };
    }
    async removeAssociation(params) {
        const { from_object_type, from_record_id, to_object_type, to_record_id } = params;
        await this.makeHubSpotApiRequest(`/crm/v4/objects/${from_object_type}/${from_record_id}/associations/${to_object_type}/${to_record_id}`, 'DELETE');
        return { operation: 'remove_association', success: true, error: '' };
    }
    // =====================================================================
    // Pipelines
    // =====================================================================
    async listPipelines(params) {
        const { object_type } = params;
        const response = (await this.makeHubSpotApiRequest(`/crm/v3/pipelines/${object_type}`, 'GET'));
        return {
            operation: 'list_pipelines',
            success: true,
            pipelines: (response.results ?? []),
            error: '',
        };
    }
    // =====================================================================
    // Notes
    // =====================================================================
    async createNote(params) {
        const { note_body, associations, timestamp } = params;
        const body = {
            properties: {
                hs_note_body: note_body,
                hs_timestamp: timestamp || new Date().toISOString(),
            },
            associations: associations.map((assoc) => ({
                to: { id: assoc.record_id },
                types: [
                    {
                        associationCategory: 'HUBSPOT_DEFINED',
                        associationTypeId: HubSpotBubble.NOTE_ASSOC_TYPES[assoc.object_type] ?? 202,
                    },
                ],
            })),
        };
        const response = (await this.makeHubSpotApiRequest('/crm/v3/objects/notes', 'POST', body));
        return {
            operation: 'create_note',
            success: true,
            note: {
                id: response.id,
                properties: (response.properties ?? {}),
            },
            error: '',
        };
    }
    // =====================================================================
    // Account
    // =====================================================================
    async getAccountInfo() {
        const response = await this.makeHubSpotApiRequest('/account-info/v3/details', 'GET');
        return {
            operation: 'get_account_info',
            success: true,
            account: response,
            error: '',
        };
    }
}
//# sourceMappingURL=hubspot.js.map