<?php

declare(strict_types=1);

namespace App\Module\Mail\Infrastructure\Controller;

use App\Module\Mail\Domain\Repository\MailMessageRepositoryInterface;
use App\Module\Mail\Domain\Repository\TaskMailLinkRepositoryInterface;
use App\Module\Mail\Infrastructure\Security\MailAccessChecker;
use App\Module\ProjectManagement\Domain\Repository\TaskRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/api/mail/messages/{id}/link-task/{taskId}', name: 'mail_unlink_task', methods: ['DELETE'], priority: 1, requirements: ['id' => '\d+', 'taskId' => '\d+'])]
#[IsGranted('IS_AUTHENTICATED_FULLY')]
class MailUnlinkTaskController extends AbstractController
{
    public function __construct(
        private readonly MailMessageRepositoryInterface $messageRepository,
        private readonly TaskMailLinkRepositoryInterface $linkRepository,
        private readonly TaskRepositoryInterface $taskRepository,
        private readonly EntityManagerInterface $em,
        private readonly MailAccessChecker $accessChecker,
    ) {}

    public function __invoke(int $id, int $taskId): JsonResponse
    {
        $this->accessChecker->ensureCanAccessMail($this->getUser());

        $message = $this->messageRepository->findById($id);
        if (null === $message) {
            throw new NotFoundHttpException('Message not found');
        }

        $task = $this->taskRepository->findById($taskId);
        if (null === $task) {
            throw new NotFoundHttpException('Task not found');
        }

        $link = $this->linkRepository->findByTaskAndMessage($task, $message);
        if (null === $link) {
            throw new NotFoundHttpException('Link not found');
        }

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

        return $this->json(null, Response::HTTP_NO_CONTENT);
    }
}
