<?php

declare(strict_types=1);

namespace App\State\Processor\Access;

use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\ApiResources\Access\AdminAccess;
use App\Entity\Access\Access;
use App\Service\Access\AdminAccessUtils;
use App\Service\Access\Utils as AccessUtils;
use App\Service\Core\ContactPointUtils;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Response;

/**
 * Classe AdminAccessProcessor qui est un custom dataPersister gérant la resource AdminAccess.
 */
class AdminAccessProcessor implements ProcessorInterface
{
    public function __construct(
        private Security $security,
        private EntityManagerInterface $entityManager,
        private AccessUtils $accessUtils,
        private ContactPointUtils $contactPointUtils,
        private AdminAccessUtils $adminAccessUtils,
    ) {
    }

    /**
     * @param mixed[] $uriVariables
     * @param mixed[] $context
     *
     * @throws \Exception
     */
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ?AdminAccess
    {
        if ($operation instanceof Delete) {
            throw new \RuntimeException('not supported', Response::HTTP_METHOD_NOT_ALLOWED);
        }

        /** @var Access $access */
        $access = $this->security->getUser();

        $administrator = $this->accessUtils->findAdminFor($access->getOrganization());
        if (!$administrator) {
            throw new \RuntimeException('administrator_not_found', 404);
        }

        $contactPoint = $this->contactPointUtils->getPersonContactPointPrincipal($administrator);
        if (!$contactPoint) {
            throw new \RuntimeException('administrator_contact_point_not_found', 404);
        }

        $contactPoint->setEmail($data->getEmail());
        $this->entityManager->persist($contactPoint);
        $this->entityManager->flush();

        return $this->adminAccessUtils->getAdminAccess($access->getOrganization());
    }
}
