<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Controller;

use Chill\DocStoreBundle\Service\Signature\PDFSignatureZoneAvailable;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
use Chill\MainBundle\Security\Authorization\EntityWorkflowStepSignatureVoter;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Twig\Environment;

final readonly class WorkflowAddSignatureController
{
    public function __construct(
        private EntityWorkflowManager $entityWorkflowManager,
        private PDFSignatureZoneAvailable $PDFSignatureZoneAvailable,
        private NormalizerInterface $normalizer,
        private Environment $twig,
        private UrlGeneratorInterface $urlGenerator,
        private Security $security,
    ) {}

    #[Route(path: '/{_locale}/main/workflow/signature/{id}/sign', name: 'chill_main_workflow_signature_add', methods: 'GET')]
    public function __invoke(EntityWorkflowStepSignature $signature, Request $request): Response
    {
        if (!$this->security->isGranted(EntityWorkflowStepSignatureVoter::SIGN, $signature)) {
            throw new AccessDeniedHttpException('not authorized to sign this step');
        }

        $entityWorkflow = $signature->getStep()->getEntityWorkflow();

        if (EntityWorkflowSignatureStateEnum::PENDING !== $signature->getState()) {
            if ($request->query->has('returnPath')) {
                return new RedirectResponse($request->query->get('returnPath'));
            }

            return new RedirectResponse(
                $this->urlGenerator->generate('chill_main_workflow_show', ['id' => $entityWorkflow->getId()])
            );
        }

        $storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
        if (null === $storedObject) {
            throw new NotFoundHttpException('No stored object found');
        }

        $zones = $this->PDFSignatureZoneAvailable->getAvailableSignatureZones($entityWorkflow);

        $signatureClient = [];
        $signatureClient['id'] = $signature->getId();
        $signatureClient['storedObject'] = $this->normalizer->normalize($storedObject, 'json');
        $signatureClient['zones'] = $zones;

        return new Response(
            $this->twig->render(
                '@ChillMain/Workflow/signature_sign.html.twig',
                ['signature' => $signatureClient]
            )
        );
    }
}
