<?php

namespace BitApps\PiPro\src\Integrations\Gmail;

// Prevent direct script access
if (!\defined('ABSPATH')) {
    exit;
}


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;

class GmailAction implements ActionInterface
{
    public const AUTH_TOKEN_URL = 'https://oauth2.googleapis.com/token';

    private GmailService $gmailService;

    private NodeInfoProvider $nodeInfoProvider;

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

    /**
     * Execute the action.
     */
    public function execute(): array
    {
        $executedNodeAction = $this->executeMachine();

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

    private function executeGmailAction(): array
    {
        $machineSlug = $this->nodeInfoProvider->getMachineSlug();
        $inputData = $this->nodeInfoProvider->getFieldMapData();

        switch ($machineSlug) {
            case 'sendEmail':
                $toEmails = $this->nodeInfoProvider->getFieldMapRepeaters('email-to.value', false, false);
                $ccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('cc-email.value', false, false);
                $bccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('bcc-email.value', false, false);
                $attachments = $this->nodeInfoProvider->getFieldMapRepeaters('attachment.value', false, false);

                return $this->gmailService->sendEmail($inputData, $toEmails, $ccEmails, $bccEmails, $attachments);

                break;

            case 'findEmail':
                return $this->gmailService->findEmail($inputData);

                break;

            case 'createDraftEmail':
                $toEmails = $this->nodeInfoProvider->getFieldMapRepeaters('email-to.value', false, false);
                $ccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('cc-email.value', false, false);
                $bccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('bcc-email.value', false, false);
                $attachments = $this->nodeInfoProvider->getFieldMapRepeaters('attachment.value', false, false);

                return $this->gmailService->createDraftEmail($inputData, $toEmails, $ccEmails, $bccEmails, $attachments);

                break;

            case 'deleteEmail':
                return $this->gmailService->deleteEmail($inputData);

                break;

            case 'getEmailDetails':
                return $this->gmailService->getEmailDetails($inputData);

                break;

            case 'getLabels':
                return $this->gmailService->getLabels($inputData);

                break;

            case 'addLabelToEmail':
                return $this->gmailService->addLabelToEmail($inputData);

                break;

            case 'removeLabelToEmail':
                return $this->gmailService->removeLabelToEmail($inputData);

                break;

            case 'sendDraft':
                return $this->gmailService->sendDraft($inputData);

                break;

            case 'replyToEmail':
                $toEmails = $this->nodeInfoProvider->getFieldMapRepeaters('email-to.value', false, false);
                $ccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('cc-email.value', false, false);
                $bccEmails = $this->nodeInfoProvider->getFieldMapRepeaters('bcc-email.value', false, false);
                $attachments = $this->nodeInfoProvider->getFieldMapRepeaters('attachment.value', false, false);

                return $this->gmailService->replyToEmail($inputData, $toEmails, $ccEmails, $bccEmails, $attachments);

                break;

            default:
                return ['status_code' => 400, 'payload' => [], 'response' => __('Invalid action', 'bit-pi')];
        }
    }

    private function executeMachine(): array
    {
        $configs = $this->nodeInfoProvider->getFieldMapConfigs();
        $headers = $this->getAuthorizationHeader($configs['connection-id']['value']);

        if (isset($headers['error'])) {
            return $headers;
        }

        $this->gmailService = new GmailService(new HttpClient(['headers' => $headers]), $headers);

        return $this->executeGmailAction();
    }

    private function getAuthorizationHeader($connectionId): array
    {
        $accessToken = AuthorizationFactory::getAuthorizationHandler(
            AuthorizationType::OAUTH2,
            $connectionId
        )->setRefreshTokenUrl(self::AUTH_TOKEN_URL)->getAccessToken();

        if (!\is_string($accessToken)) {
            return $accessToken;
        }

        return [
            'Authorization' => $accessToken,
            'Content-Type'  => 'application/json'
        ];
    }
}
