<?php

namespace PublishPress\FuturePro\Modules\Workflows\Domain\Steps\Actions\Runners;

use PublishPress\Future\Framework\Logger\LoggerInterface;
use PublishPress\Future\Modules\Workflows\Domain\Steps\Actions\Definitions\Conditional;
use PublishPress\Future\Modules\Workflows\Interfaces\ExecutionContextInterface;
use PublishPress\Future\Modules\Workflows\Interfaces\StepProcessorInterface;
use PublishPress\Future\Modules\Workflows\Interfaces\StepRunnerInterface;
use PublishPress\Future\Modules\Workflows\Interfaces\JsonLogicEngineInterface;

class ConditionalRunner implements StepRunnerInterface
{
    /**
     * @var StepProcessorInterface
     */
    private $stepProcessor;

    /**
     * @var ExecutionContextInterface
     */
    private $executionContext;

    /**
     * @var JsonLogicEngineInterface
     */
    private $jsonLogicEngine;

    /**
     * @var LoggerInterface
     */
    private $logger;

    public function __construct(
        StepProcessorInterface $stepProcessor,
        ExecutionContextInterface $executionContext,
        JsonLogicEngineInterface $jsonLogicEngine,
        LoggerInterface $logger
    ) {
        $this->stepProcessor = $stepProcessor;
        $this->executionContext = $executionContext;
        $this->jsonLogicEngine = $jsonLogicEngine;
        $this->logger = $logger;
    }

    public static function getNodeTypeName(): string
    {
        return Conditional::getNodeTypeName();
    }

    public function setup(array $step): void
    {
        $this->stepProcessor->executeSafelyWithErrorHandling(
            $step,
            function ($step) {
                $expression = $step['node']['data']['settings']['conditions']['json'];
                $expression = $this->executionContext->resolveExpressionsInJsonLogic((array)$expression);

                $conditionResult = $this->jsonLogicEngine->apply($expression, []);

                $branch = $conditionResult ? 'true' : 'false';

                $nodeSlug = $this->stepProcessor->getSlugFromStep($step);

                $this->executionContext->setVariable($nodeSlug, [
                    'branch' => $branch,
                ]);

                $this->logger->debug(
                    $this->stepProcessor->prepareLogMessage(
                        'Conditional split following to branch "%1$s" | Slug: %2$s',
                        $branch,
                        $nodeSlug
                    )
                );

                $this->stepProcessor->runNextSteps($step, $branch);
            },
            $step
        );
    }
}
