<?php

declare(strict_types=1);

namespace App\Module\ProjectManagement\Infrastructure\Mcp\Tool\Task;

use App\Module\ProjectManagement\Domain\Enum\RecurrenceType;
use App\Module\ProjectManagement\Domain\Repository\TaskRecurrenceRepositoryInterface;
use App\Module\ProjectManagement\Infrastructure\Service\CalDavService;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
use Mcp\Capability\Attribute\McpTool;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

use function sprintf;

#[McpTool(name: 'update-task-recurrence', description: 'Update an existing task recurrence pattern.')]
class UpdateTaskRecurrenceTool
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly TaskRecurrenceRepositoryInterface $taskRecurrenceRepository,
        private readonly Security $security,
        private readonly CalDavService $calDavService,
    ) {}

    public function __invoke(
        int $recurrenceId,
        ?string $type = null,
        ?int $interval = null,
        ?array $daysOfWeek = null,
        ?int $dayOfMonth = null,
        ?int $weekOfMonth = null,
        ?string $endDate = null,
        ?int $maxOccurrences = null,
    ): string {
        if (!$this->security->isGranted('ROLE_USER')) {
            throw new AccessDeniedException('Access denied: ROLE_USER required.');
        }

        $recurrence = $this->taskRecurrenceRepository->findById($recurrenceId);
        if (null === $recurrence) {
            throw new InvalidArgumentException(sprintf('TaskRecurrence with ID %d not found.', $recurrenceId));
        }

        if (null !== $type) {
            $recurrence->setType(RecurrenceType::from($type));
        }
        if (null !== $interval) {
            $recurrence->setInterval($interval);
        }
        if (null !== $daysOfWeek) {
            $recurrence->setDaysOfWeek($daysOfWeek);
        }
        if (null !== $dayOfMonth) {
            $recurrence->setDayOfMonth($dayOfMonth);
        }
        if (null !== $weekOfMonth) {
            $recurrence->setWeekOfMonth($weekOfMonth);
        }
        if (null !== $endDate) {
            $recurrence->setEndDate(new DateTimeImmutable($endDate));
        }
        if (null !== $maxOccurrences) {
            $recurrence->setMaxOccurrences($maxOccurrences);
        }

        $this->entityManager->flush();

        foreach ($recurrence->getTasks() as $task) {
            $this->calDavService->syncTask($task);
        }
        $this->entityManager->flush();

        return json_encode([
            'id'             => $recurrence->getId(),
            'type'           => $recurrence->getType()?->value,
            'interval'       => $recurrence->getInterval(),
            'daysOfWeek'     => $recurrence->getDaysOfWeek(),
            'dayOfMonth'     => $recurrence->getDayOfMonth(),
            'weekOfMonth'    => $recurrence->getWeekOfMonth(),
            'endDate'        => $recurrence->getEndDate()?->format('Y-m-d'),
            'maxOccurrences' => $recurrence->getMaxOccurrences(),
        ]);
    }
}
