<?php

declare(strict_types=1);

namespace App\Mcp\Tool\ModelType;

use App\DTO\SyncConfirmation;
use App\Mcp\Tool\McpToolHelper;
use App\Repository\ModelTypeRepository;
use App\Service\ModelTypeSyncService;
use Doctrine\ORM\EntityManagerInterface;
use Mcp\Capability\Attribute\McpTool;
use Mcp\Schema\Result\CallToolResult;
use Symfony\Bundle\SecurityBundle\Security;

#[McpTool(
    name: 'sync_model_type',
    description: 'Preview or sync a model type structure. Action "preview" shows what would change. Action "sync" applies the pending structure. Requires ROLE_GESTIONNAIRE.',
)]
class SyncModelTypeTool
{
    use McpToolHelper;

    public function __construct(
        private readonly ModelTypeRepository $modelTypes,
        private readonly ModelTypeSyncService $syncService,
        private readonly EntityManagerInterface $em,
        private readonly Security $security,
    ) {}

    public function __invoke(
        string $modelTypeId,
        string $action,
        ?array $structure = null,
        bool $confirmDeletions = false,
        bool $confirmTypeChanges = false,
    ): CallToolResult {
        $this->requireRole($this->security, 'ROLE_GESTIONNAIRE');

        if (!in_array($action, ['preview', 'sync'], true)) {
            $this->mcpError('validation', "Invalid action '{$action}'. Must be 'preview' or 'sync'.");
        }

        $mt = $this->modelTypes->find($modelTypeId);

        if (!$mt) {
            $this->mcpError('not_found', "ModelType not found: {$modelTypeId}");
        }

        if ('preview' === $action) {
            $result = $this->syncService->preview($mt, $structure ?? []);

            return $this->jsonResponse($result->jsonSerialize());
        }

        // sync action
        $confirmation = new SyncConfirmation(
            confirmDeletions: $confirmDeletions,
            confirmTypeChanges: $confirmTypeChanges,
        );

        $result = $this->em->wrapInTransaction(function () use ($mt, $confirmation) {
            return $this->syncService->execute($mt, $confirmation);
        });

        return $this->jsonResponse($result->jsonSerialize());
    }
}
