<?php

namespace idoit\Module\SyneticsFlows\Controller;

use idoit\Exception\Exception;
use idoit\Module\SyneticsFlows\Automation\Automation;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\InvocationContext;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\ObjectContext;
use idoit\Module\SyneticsFlows\Automation\Trigger\Invocation\TimeInvocation;
use idoit\Module\SyneticsFlows\Auth;
use idoit\Module\SyneticsFlows\Controller\Response\MalformedResponse;
use idoit\Module\SyneticsFlows\Template\TemplateFactory;
use idoit\Module\SyneticsFlows\Validation\ValidationMessage;
use isys_application;
use isys_auth;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;

/**
 * Template controller
 *
 * @package   idoit\Module\synetics_flows\Processor
 * @copyright synetics
 * @license   https://www.i-doit.com/
 */
class TemplateController extends BaseController
{
    public function preview(Request $request): Response
    {
        if (!Auth::instance()->manageFlows(isys_auth::VIEW)) {
            return JSONResponseFactory::accessDenied();
        }

        $params = $this->extractData($request);
        $template = $params['template'];
        $objectId = $params['objectId'];
        $templateFactory = isys_application::instance()->container->get('idoit.flows.template');
        if (!$templateFactory instanceof TemplateFactory) {
            throw new Exception('Environment is not correctly configured.');
        }
        $invocation = new TimeInvocation();
        $invocation->setContext($objectId ? new ObjectContext($objectId, '') : InvocationContext::fromEnvironment());
        $content = $templateFactory->forInvocation($invocation, new Automation());
        return new JsonResponse($content->process($template));
    }

    public function validate(Request $request): Response
    {
        if (!Auth::instance()->manageFlows(isys_auth::EDIT) && !Auth::instance()->manageFlows(isys_auth::CREATE)) {
            return JSONResponseFactory::accessDenied();
        }
        $params = $this->extractData($request);
        $template = $params['template'];
        $templateFactory = isys_application::instance()->container->get('idoit.flows.template');
        if (!$templateFactory instanceof TemplateFactory) {
            throw new Exception('Environment is not correctly configured.');
        }
        $invocation = new TimeInvocation();
        $content = $templateFactory->forInvocation($invocation, new Automation());
        $lines = preg_split("/\s/", $template);
        try {
            $content->process(implode("\n", $lines));
        } catch (SyntaxError|RuntimeError $error) {
            $errorLine = $error->getTemplateLine() - 1;
            $lineWithError = $lines[$errorLine];
            $start = array_reduce(array_slice($lines, 0, $errorLine), fn (int $length, string $current) => $length + mb_strlen($current) + 1, 0);
            $end = $start + mb_strlen($lineWithError);
            return new MalformedResponse([
                new ValidationMessage(["$start", "$end"], $error->getRawMessage()),
            ]);
        }
        return new JsonResponse([]);
    }
}
