<?php

namespace BitApps\PiPro\src\Integrations\GoogleDrive;

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;
use InvalidArgumentException;

class GoogleDriveAction implements ActionInterface
{
    public const BASE_URL = 'https://www.googleapis.com';

    private NodeInfoProvider $nodeInfoProvider;

    private GoogleDriveService $googleDriveService;

    private $accessToken;

    public function __construct(NodeInfoProvider $nodeInfoProvider)
    {
        $this->nodeInfoProvider = $nodeInfoProvider;
        $this->accessToken = AuthorizationFactory::getAuthorizationHandler(
            AuthorizationType::OAUTH2,
            $this->nodeInfoProvider->getFieldMapConfigs('connection-id.value')
        )->getAccessToken();
    }

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

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

    private function executeMachine($machineSlug)
    {
        switch ($machineSlug) {
            case 'uploadFile':
                return $this->googleDriveService->uploadFile($this->nodeInfoProvider, $this->accessToken);

            case 'getFile':
                return $this->googleDriveService->getFile($this->nodeInfoProvider);

            case 'downloadFile':
                return $this->googleDriveService->downloadFile($this->nodeInfoProvider);

            case 'copyFile':
                return $this->googleDriveService->copyFile($this->nodeInfoProvider);

            case 'deleteFile':
                return $this->googleDriveService->deleteFile($this->nodeInfoProvider);

            case 'moveFile':
                return $this->googleDriveService->moveFile($this->nodeInfoProvider);

            case 'updateFile':
                return $this->googleDriveService->updateFile($this->nodeInfoProvider);

            case 'shareFile':
                return $this->googleDriveService->shareFile($this->nodeInfoProvider);

            case 'createFileFromText':
                return $this->googleDriveService->createFileFromText($this->nodeInfoProvider);

            case 'createFolder':
                return $this->googleDriveService->createFolder($this->nodeInfoProvider);

            case 'deleteFolder':
                return $this->googleDriveService->deleteFolder($this->nodeInfoProvider);

            case 'shareFolder':
                return $this->googleDriveService->shareFolder($this->nodeInfoProvider);

            case 'createDrive':
                return $this->googleDriveService->createDrive($this->nodeInfoProvider);

            case 'getDrive':
                return $this->googleDriveService->getDrive($this->nodeInfoProvider);

            case 'listDrives':
                return $this->googleDriveService->listDrives($this->nodeInfoProvider);

            case 'updateDrive':
                return $this->googleDriveService->updateDrive($this->nodeInfoProvider);

            case 'deleteDrive':
                return $this->googleDriveService->deleteDrive($this->nodeInfoProvider);

            case 'searchFilesFolders':
                return $this->googleDriveService->searchFilesFolders($this->nodeInfoProvider);

            default:
                throw new InvalidArgumentException("Unknown action: {$machineSlug}");
        }
    }

    private function executeGoogleDriveAction()
    {
        $machineSlug = $this->nodeInfoProvider->getMachineSlug();

        $connectionId = $this->nodeInfoProvider->getFieldMapConfigs('connection-id.value');

        if (!$connectionId) {
            return [
                'response'    => ['error' => 'Connection ID is required'],
                'payload'     => [],
                'status_code' => 400,
            ];
        }

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

        $this->googleDriveService = new GoogleDriveService($httpClient, static::BASE_URL);

        return $this->executeMachine($machineSlug);
    }
}
