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


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

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

  if (operation === 'create') {
    const data = {
      name: this.getNodeParameter('name', i) as string,
      pipelineId: this.getNodeParameter('pipelineId', i) as string,
      pipelineStageId: this.getNodeParameter('pipelineStageId', i) as string,
      status: this.getNodeParameter('status', i) as string,
      contactId: this.getNodeParameter('contactId', i) as string,
      ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
    };

    return GHLEngine.createOpportunity(data);
  }

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

    formatCustomFields(data);

    return GHLEngine.updateOpportunity(opportunityId, data);
  }

  if (operation === 'get') {
    const opportunityId = this.getNodeParameter('opportunityId', i) as string;
    return GHLEngine.getOpportunity(opportunityId);
  }

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

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

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

  if (operation === 'updateStage') {
    const opportunityId = this.getNodeParameter('opportunityId', i) as string;
    const stageId = this.getNodeParameter('stageId', i) as string;
    return GHLEngine.updateOpportunityStage(opportunityId, stageId);
  }

  if (operation === 'updateStatus') {
    const opportunityId = this.getNodeParameter('opportunityId', i) as string;
    const status = this.getNodeParameter('status', i) as string;
    return GHLEngine.updateOpportunityStatus(opportunityId, status);
  }

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

    formatCustomFields(data);


    const opportunity = await GHLEngine.findOpportunity({ contact_id: contactId });

    if (opportunity?.id) {
      return GHLEngine.updateOpportunity(opportunity.id, data);
    }

    return GHLEngine.createOpportunity(data);
  }

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

    const data = {
      name,
      contactId,
      ...this.getNodeParameter('additionalFields', i, {}) as IDataObject,
    };

    formatCustomFields(data);


    const opportunity = await GHLEngine.findOpportunity({ contact_id: contactId });

    if (opportunity?.id) {
      return GHLEngine.updateOpportunity(opportunity.id, data);
    }

    return GHLEngine.createOpportunity(data);
  }

  if (operation === 'updateStage') {
    const opportunityId = this.getNodeParameter('opportunityId', i) as string;
    const stageId = this.getNodeParameter('stageId', i) as string;

    return GHLEngine.updateOpportunityStage(opportunityId, stageId);
  }

  if (operation === 'updateStatus') {
    const opportunityId = this.getNodeParameter('opportunityId', i) as string;
    const status = this.getNodeParameter('status', i) as string;

    return GHLEngine.updateOpportunityStatus(opportunityId, status);
  }

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