<?php

declare(strict_types=1);

namespace App\Module\Mail\Infrastructure\Controller;

use App\Module\Mail\Domain\Repository\MailFolderRepositoryInterface;
use App\Module\Mail\Domain\Repository\MailMessageRepositoryInterface;
use App\Module\Mail\Infrastructure\Security\MailAccessChecker;
use DateTimeInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/api/mail/folders/{folderPath}/messages', name: 'mail_messages_list', methods: ['GET'], priority: 1, requirements: ['folderPath' => '.+'])]
#[IsGranted('IS_AUTHENTICATED_FULLY')]
class MailMessagesListController extends AbstractController
{
    public function __construct(
        private readonly MailFolderRepositoryInterface $folderRepository,
        private readonly MailMessageRepositoryInterface $messageRepository,
        private readonly MailAccessChecker $accessChecker,
    ) {}

    public function __invoke(Request $request, string $folderPath): JsonResponse
    {
        $this->accessChecker->ensureCanAccessMail($this->getUser());

        $decodedPath = urldecode($folderPath);

        $folder = $this->folderRepository->findByPath($decodedPath);
        if (null === $folder) {
            throw new NotFoundHttpException(sprintf('Folder "%s" not found', $decodedPath));
        }

        $limit  = min((int) $request->query->get('limit', 50), 100);
        $cursor = $request->query->get('cursor');

        $result = $this->messageRepository->findByFolderCursor($folder, $limit, $cursor ?: null);

        $messages = array_map(static fn ($m) => [
            'id'             => $m->getId(),
            'messageId'      => $m->getMessageId(),
            'uid'            => $m->getUid(),
            'subject'        => $m->getSubject(),
            'fromAddress'    => $m->getFromAddress(),
            'fromName'       => $m->getFromName(),
            'toAddresses'    => $m->getToAddresses(),
            'ccAddresses'    => $m->getCcAddresses(),
            'sentAt'         => $m->getSentAt()->format(DateTimeInterface::ATOM),
            'isRead'         => $m->isRead(),
            'isFlagged'      => $m->isFlagged(),
            'hasAttachments' => $m->hasAttachments(),
            'snippet'        => $m->getSnippet(),
        ], $result['messages']);

        return $this->json([
            'messages'   => $messages,
            'nextCursor' => $result['nextCursor'],
        ]);
    }
}
