<?php

namespace BitApps\PiPro\src\Integrations\Apify;

use BitApps\Pi\Helpers\MixInputHandler;
use BitApps\Pi\Helpers\Utility;
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 ApifyAction implements ActionInterface
{
    private NodeInfoProvider $nodeInfoProvider;

    private ApifyService $apifyService;

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

    public function execute(): array
    {
        $executedNodeAction = $this->executeApifyAction();

        return Utility::formatResponseData(
            $executedNodeAction['status_code'],
            $executedNodeAction['payload'],
            $executedNodeAction['response']
        );
    }

    private function executeMachine($machineSlug, $configs, $fieldMapData)
    {
        switch ($machineSlug) {
            case 'runActor':
                return $this->apifyService->runActor($configs['actor-id']['value'], $fieldMapData);

            case 'scrapeSingleUrl':
                return $this->apifyService->scrapeSingleUrl($fieldMapData);

            case 'getLastActor':
                return $this->apifyService->getLastActor($configs['actor-id']['value'], $fieldMapData);

            case 'getLastTask':
                return $this->apifyService->getLastTask($configs['task-id']['value'], $fieldMapData);

            case 'runTask':
                return $this->apifyService->runTask($configs['task-id']['value'], $fieldMapData);

            case 'getUserRunsList':
                return $this->apifyService->getUserRunsList($fieldMapData);

            case 'getRuns':
                return $this->apifyService->getRuns($configs['actor-id']['value'], $fieldMapData);

            case 'getDatasetItems':
                $mixInputDatasetId = $this->nodeInfoProvider->getFieldMapConfigs('dataset-id.value');
                $datasetId = MixInputHandler::replaceMixTagValue($mixInputDatasetId);

                return $this->apifyService->getDatasetItems($datasetId, $fieldMapData);

            case 'getKeyValueRecord':
                $mixInputStoreId = $this->nodeInfoProvider->getFieldMapConfigs('key-value-store-id.value');
                $keyValueStoreId = MixInputHandler::replaceMixTagValue($mixInputStoreId);
                $mixInputRecordKey = $this->nodeInfoProvider->getFieldMapConfigs('record-key.value');
                $recordKey = MixInputHandler::replaceMixTagValue($mixInputRecordKey);

                return $this->apifyService->getKeyValueRecord($keyValueStoreId, $recordKey);

            case 'createKeyValueRecord':
                $mixInputStoreId = $this->nodeInfoProvider->getFieldMapConfigs('key-value-store-id.value');
                $keyValueStoreId = MixInputHandler::replaceMixTagValue($mixInputStoreId);
                $mixInputRecordKey = $this->nodeInfoProvider->getFieldMapConfigs('record-key.value');
                $recordKey = MixInputHandler::replaceMixTagValue($mixInputRecordKey);

                return $this->apifyService->createKeyValueRecord($keyValueStoreId, $recordKey, $fieldMapData['recordValue']);
        }
    }

    private function executeApifyAction()
    {
        $machineSlug = $this->nodeInfoProvider->getMachineSlug();
        $configs = $this->nodeInfoProvider->getFieldMapConfigs();
        $fieldMapData = $this->nodeInfoProvider->getFieldMapData();

        $token = AuthorizationFactory::getAuthorizationHandler(
            AuthorizationType::BEARER_TOKEN,
            $configs['connection-id']
        )->getAccessToken();

        $httpClient = new HttpClient(
            [
                'headers' => [
                    'Content-Type'  => 'application/json',
                    'Authorization' => $token
                ],
            ]
        );

        $this->apifyService = new ApifyService($httpClient);

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