import { IExecuteFunctions, IDataObject } from 'n8n-workflow';
import { GoHighLevelManager } from '@src/utils/gohighlevel';
import { IContact } from './contact.types';

function formatCustomFields(data: any) {
  if (data.customFields) {
    data.customFields = data.customFields.values as unknown as IContact['customFields'];
  }
}

export async function handleContactOperations(
  this: IExecuteFunctions,
  operation: string,
  i: number,
): Promise<IDataObject | IDataObject[]> {
  const GHLEngine = await GoHighLevelManager.getInstance(this);

  if (operation === 'create') {
    const data = {
      email: this.getNodeParameter('email', i) as string,
      phone: this.getNodeParameter('phone', i) as string,
      ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
    };

    return GHLEngine.createContact(data);
  }

  if (operation === 'update') {
    const contactId = this.getNodeParameter('contactId', i) as string;
    const data = {
      ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
    };

    formatCustomFields(data);

    return GHLEngine.updateContact(contactId, data);
  }

  if (operation === 'get') {
    const contactId = this.getNodeParameter('contactId', i) as string;

    return GHLEngine.getContact(contactId);
  }

  if (operation === 'getAll') {
    const returnAll = this.getNodeParameter('returnAll', i) as boolean;
    const filters = this.getNodeParameter('filters', i) as IDataObject;

    if (returnAll) {
      return GHLEngine.getContacts({ params: filters });
    } else {
      const limit = this.getNodeParameter('limit', i) as number;
      return GHLEngine.getContacts({ params: { ...filters, limit } });
    }
  }

  if (operation === 'delete') {
    const contactId = this.getNodeParameter('contactId', i) as string;
    return GHLEngine.deleteContact(contactId);
  }

  if (operation === 'addTag') {
    const contactId = this.getNodeParameter('contactId', i) as string;
    const tags = (this.getNodeParameter('tags', i) as string).split(',').map(tag => tag.trim());

    return GHLEngine.addTagToContact(contactId, tags);
  }

  if (operation === 'removeTag') {
    const contactId = this.getNodeParameter('contactId', i) as string;
    const tags = (this.getNodeParameter('tags', i) as string).split(',').map(tag => tag.trim());

    return GHLEngine.removeTagFromContact(contactId, tags);
  }

  // if (operation === 'addToSequence') {
  //   const contactId = this.getNodeParameter('contactId', i) as string;
  //   const sequenceId = this.getNodeParameter('sequenceId', i) as string;
  //   return goHighLevelApiRequest.call(this, 'POST', `/v2/${resource}/${contactId}/sequences/${sequenceId}`);
  // }

  // if (operation === 'removeFromSequence') {
  //   const contactId = this.getNodeParameter('contactId', i) as string;
  //   const sequenceId = this.getNodeParameter('sequenceId', i) as string;
  //   return goHighLevelApiRequest.call(this, 'DELETE', `/v2/${resource}/${contactId}/sequences/${sequenceId}`);
  // }

  // find
  if (operation === 'find') {
    const email = this.getNodeParameter('email', i) as string;

    return await GHLEngine.findContactByEmail(email);
  }

  // findOrCreate
  if (operation === 'findOrCreate') {
    const email = this.getNodeParameter('email', i) as string;
    const contact = await GHLEngine.findContactByEmail(email);

    if (!contact) {
      const data = {
        email,
        ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
      };

      formatCustomFields(data);

      return GHLEngine.createContact(data);
    }

    return contact;
  }

  // updateOrCreate
  if (operation === 'updateOrCreate') {
    const email = this.getNodeParameter('email', i) as string;
    const data = {
      email,
      ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
    };

    formatCustomFields(data);

    const contact = await GHLEngine.findContactByEmail(email);

    if (!contact?.id) {
      return GHLEngine.createContact(data);
    }

    return GHLEngine.updateContact(contact.id, data);
  }


  throw new Error(`Unknown operation: ${operation}`);
}
