<?php

namespace BitApps\PiPro\src\Integrations\GoHighLevel;

use BitApps\Pi\src\Authorization\AuthorizationFactory;
use BitApps\Pi\src\Authorization\AuthorizationType;
use BitApps\Pi\src\Flow\NodeInfoProvider;
use BitApps\Pi\src\Interfaces\ActionInterface;
use BitApps\PiPro\Deps\BitApps\WPKit\Http\Client\HttpClient;

if (!\defined('ABSPATH')) {
    exit;
}

class GoHighLevelV2Action implements ActionInterface
{
    private NodeInfoProvider $nodeInfoProvider;

    private GoHighLevelV2Service $goHighLevelV2Service;

    public function __construct(NodeInfoProvider $nodeInfoProvider)
    {
        $this->nodeInfoProvider = $nodeInfoProvider;
    }

    public function execute(): array
    {
        return $this->executeGoHighLevelV2Action();
    }

    private function executeMachine($machineSlug, $fieldMapData, $configs, $locationId)
    {
        switch ($machineSlug) {
            case 'addContact':
                $goHighLevelFields = $this->nodeInfoProvider->getFieldMapRepeaters('field-map.value', false, true, 'goHighLevelField', 'value');
                $fieldMapData = array_merge($fieldMapData, $goHighLevelFields, ['locationId' => $locationId]);

                return $this->goHighLevelV2Service->addContact($fieldMapData);

            case 'updateContact':
                $contactId = $configs['contact-id']['value'] ?? null;
                $goHighLevelFields = $this->nodeInfoProvider->getFieldMapRepeaters('field-map.value', false, true, 'goHighLevelField', 'value');
                $fieldMapData = array_merge($fieldMapData, $goHighLevelFields);

                return $this->goHighLevelV2Service->updateContact($contactId, $fieldMapData);

            case 'addContactToCampaign':
                $contactId = $configs['contact-id']['value'] ?? null;
                $campaignId = $configs['campaign-id']['value'] ?? null;

                return $this->goHighLevelV2Service->addContactToCampaign($contactId, $campaignId);

            case 'addNoteToContact':
                $contactId = $configs['contact-id']['value'] ?? null;

                return $this->goHighLevelV2Service->addNoteToContact($contactId, $fieldMapData);

            case 'searchContacts':
                return $this->goHighLevelV2Service->searchContacts($fieldMapData, $locationId);

            case 'addTask':
                $contactId = $configs['contact-id']['value'] ?? null;

                return $this->goHighLevelV2Service->addTask($contactId, $fieldMapData);

            case 'updateTask':
                $contactId = $configs['contact-id']['value'] ?? null;
                $taskId = $configs['task-id']['value'] ?? null;

                return $this->goHighLevelV2Service->updateTask($contactId, $taskId, $fieldMapData);

            case 'addOpportunity':
                $fieldMapData = array_merge($fieldMapData, ['locationId' => $locationId]);

                return $this->goHighLevelV2Service->addOpportunity($fieldMapData);

            case 'updateOpportunity':
                $opportunityId = $configs['opportunity-id']['value'] ?? null;

                return $this->goHighLevelV2Service->updateOpportunity($opportunityId, $fieldMapData);

            case 'addContactToWorkflow':
                $contactId = $configs['contact-id']['value'] ?? null;
                $workflowId = $configs['workflow-id']['value'] ?? null;

                return $this->goHighLevelV2Service->addContactToWorkflow($contactId, $workflowId);
        }
    }

    private function executeGoHighLevelV2Action()
    {
        $machineSlug = $this->nodeInfoProvider->getMachineSlug();
        $configs = $this->nodeInfoProvider->getFieldMapConfigs();
        $fieldMapData = $this->nodeInfoProvider->getFieldMapData();
        $connectionId = $configs['connection-id'];

        $authHandler = AuthorizationFactory::getAuthorizationHandler(
            AuthorizationType::OAUTH2,
            $connectionId
        );

        $accessToken = $authHandler->getAccessToken();
        $locationId = $authHandler->getAuthDetails()['locationId'];

        $httpClient = new HttpClient(
            [
                'headers' => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => $accessToken,
                    'Version'       => '2021-07-28',
                ],
            ]
        );

        $this->goHighLevelV2Service = new GoHighLevelV2Service($httpClient);

        return $this->executeMachine($machineSlug, $fieldMapData, $configs, $locationId);
    }
}
