<?php

declare(strict_types=1);

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

use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Module\Integration\Domain\Entity\TaskBookStackLink;
use App\Module\Integration\Domain\Repository\TaskBookStackLinkRepositoryInterface;
use App\Module\Integration\Infrastructure\ApiPlatform\Resource\BookStackLink;
use App\Module\ProjectManagement\Domain\Repository\TaskRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

final readonly class BookStackLinkProcessor implements ProcessorInterface
{
    public function __construct(
        private EntityManagerInterface $em,
        private TaskBookStackLinkRepositoryInterface $linkRepository,
        private TaskRepositoryInterface $taskRepository,
    ) {}

    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ?BookStackLink
    {
        if ($operation instanceof Delete) {
            return $this->handleDelete($uriVariables);
        }

        return $this->handleCreate($data, $uriVariables);
    }

    private function handleCreate(mixed $data, array $uriVariables): BookStackLink
    {
        assert($data instanceof BookStackLink);

        $taskId = $uriVariables['taskId'] ?? 0;
        $task   = $this->taskRepository->findById((int) $taskId);

        if (null === $task) {
            throw new NotFoundHttpException('Task not found.');
        }

        $link = new TaskBookStackLink();
        $link->setTask($task);
        $link->setBookstackId($data->bookstackId);
        $link->setBookstackType($data->bookstackType);
        $link->setTitle($data->title);
        $link->setUrl($data->url);

        $this->em->persist($link);
        $this->em->flush();

        $result                = new BookStackLink();
        $result->id            = $link->getId();
        $result->bookstackId   = $link->getBookstackId();
        $result->bookstackType = $link->getBookstackType();
        $result->title         = $link->getTitle();
        $result->url           = $link->getUrl();
        $result->createdAt     = $link->getCreatedAt()->format('c');

        return $result;
    }

    private function handleDelete(array $uriVariables): null
    {
        $linkId = $uriVariables['id'] ?? 0;
        $link   = $this->linkRepository->findById((int) $linkId);

        if (null === $link) {
            throw new NotFoundHttpException('Link not found.');
        }

        $this->em->remove($link);
        $this->em->flush();

        return null;
    }
}
