<?php declare(strict_types = 1);

namespace idoit\Module\SyneticsFlows\Automation\Action\ExecutionFactory;

use idoit\Module\SyneticsFlows\Automation\Action\ActionType\ActionType;
use idoit\Module\SyneticsFlows\Automation\Action\ActionType\ApiCallAction;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\ExecutionInfo;
use idoit\Module\SyneticsFlows\Automation\Action\ExecutionInfo\PerformApiCall;
use idoit\Module\SyneticsFlows\Automation\Automation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\Invocation;
use idoit\Module\SyneticsFlows\Template\TemplateFactory;
use idoit\Module\SyneticsFlows\Dto\KeyValueItem;
use idoit\Module\SyneticsFlows\Dto\ValueItem;

class ApiCallFactory implements ExecutionFactory
{
    public function __construct(private TemplateFactory $factory)
    {
    }

    public function createExecution(Invocation $invocation, Automation $automation, ActionType $actionType): ?ExecutionInfo
    {
        if (!$actionType instanceof ApiCallAction) {
            return null;
        }
        $template = $this->factory->forInvocation($invocation, $automation);

        $headers = $actionType->getAuthType()?->prepareHeaders() ?? [];
        foreach ($actionType->getHeaders() as $header) {
            if (!$header instanceof ValueItem) {
                continue;
            }
            $headers[$header->getKey()] = $template->process($header->getValue());
        }

        $queryParams = [];
        foreach ($actionType->getQueryParams() as $queryParam) {
            if (!$queryParam instanceof ValueItem) {
                continue;
            }
            $queryParams[$queryParam->getKey()] = $template->process($queryParam->getValue());
        }
        $body = $template->process($actionType->getBody());
        return new PerformApiCall(
            $actionType->getUrl(),
            $actionType->getMethod(),
            $actionType->getAuthType(),
            $headers,
            $queryParams,
            $body,
        );
    }

    public function supports(ActionType $actionType): bool
    {
        return $actionType instanceof ApiCallAction;
    }
}