<?php

declare(strict_types=1);

namespace App\Module\ProjectManagement\Infrastructure\ApiPlatform\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Post;
use ApiPlatform\State\ProcessorInterface;
use App\Module\ProjectManagement\Domain\Entity\Task;
use App\Module\ProjectManagement\Domain\Repository\TaskRepositoryInterface;
use App\Module\ProjectManagement\Infrastructure\Service\CalDavService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

/**
 * @implements ProcessorInterface<Task, Task>
 */
final readonly class TaskNumberProcessor implements ProcessorInterface
{
    /**
     * @param ProcessorInterface<Task, Task> $persistProcessor
     */
    public function __construct(
        #[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')]
        private ProcessorInterface $persistProcessor,
        private TaskRepositoryInterface $taskRepository,
        private EntityManagerInterface $entityManager,
        private CalDavService $calDavService,
    ) {}

    /**
     * @param Task $data
     */
    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
    {
        if ($operation instanceof Post && null !== $data->getProject()) {
            $result = $this->entityManager->wrapInTransaction(function () use ($data, $operation, $uriVariables, $context) {
                $maxNumber = $this->taskRepository->findMaxNumberByProjectForUpdate($data->getProject());
                $data->setNumber($maxNumber + 1);

                return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
            });

            $this->calDavService->syncTask($data);
            $this->entityManager->flush();

            return $result;
        }

        return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
    }
}
