<?php

declare(strict_types=1);

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

use App\Module\ProjectManagement\Domain\Enum\StatusCategory;
use App\Module\ProjectManagement\Domain\Repository\TaskStatusRepositoryInterface;
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-status', description: 'Update a task status (admin). Only provided fields change. category = todo|in_progress|blocked|review|done.')]
class UpdateStatusTool
{
    public function __construct(
        private readonly TaskStatusRepositoryInterface $statusRepository,
        private readonly EntityManagerInterface $entityManager,
        private readonly Security $security,
    ) {}

    public function __invoke(
        int $id,
        ?string $label = null,
        ?string $category = null,
        ?string $color = null,
        ?int $position = null,
        ?bool $isFinal = null,
    ): string {
        if (!$this->security->isGranted('ROLE_ADMIN')) {
            throw new AccessDeniedException('Access denied: ROLE_ADMIN required.');
        }

        $status = $this->statusRepository->findById($id);
        if (null === $status) {
            throw new InvalidArgumentException(sprintf('TaskStatus with ID %d not found.', $id));
        }

        if (null !== $label) {
            $status->setLabel($label);
        }
        if (null !== $category) {
            $status->setCategory(
                StatusCategory::tryFrom($category)
                    ?? throw new InvalidArgumentException(sprintf('Unknown status category "%s".', $category)),
            );
        }
        if (null !== $color) {
            $status->setColor($color);
        }
        if (null !== $position) {
            $status->setPosition($position);
        }
        if (null !== $isFinal) {
            $status->setIsFinal($isFinal);
        }

        $this->entityManager->flush();

        return json_encode([
            'id'         => $status->getId(),
            'label'      => $status->getLabel(),
            'color'      => $status->getColor(),
            'position'   => $status->getPosition(),
            'isFinal'    => $status->getIsFinal(),
            'category'   => $status->getCategory()->value,
            'workflowId' => $status->getWorkflow()?->getId(),
        ]);
    }
}
