<?php

declare(strict_types=1);

namespace App\Controller;

use App\DTO\SyncConfirmation;
use App\Repository\ModelTypeRepository;
use App\Service\ModelTypeSyncService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/api/model_types/{id}')]
final class ModelTypeSyncController extends AbstractController
{
    public function __construct(
        private readonly ModelTypeRepository $modelTypes,
        private readonly ModelTypeSyncService $syncService,
        private readonly EntityManagerInterface $em,
    ) {}

    #[Route('/sync-preview', name: 'api_model_type_sync_preview', methods: ['POST'])]
    public function preview(string $id, Request $request): JsonResponse
    {
        $this->denyAccessUnlessGranted('ROLE_GESTIONNAIRE');

        $modelType = $this->modelTypes->find($id);

        if (!$modelType) {
            return new JsonResponse(
                ['message' => 'Catégorie introuvable.'],
                Response::HTTP_NOT_FOUND,
            );
        }

        $body      = json_decode($request->getContent(), true);
        $structure = $body['structure'] ?? [];

        $result = $this->syncService->preview($modelType, $structure);

        return new JsonResponse($result);
    }

    #[Route('/sync', name: 'api_model_type_sync', methods: ['POST'])]
    public function sync(string $id, Request $request): JsonResponse
    {
        $this->denyAccessUnlessGranted('ROLE_GESTIONNAIRE');

        $modelType = $this->modelTypes->find($id);

        if (!$modelType) {
            return new JsonResponse(
                ['message' => 'Catégorie introuvable.'],
                Response::HTTP_NOT_FOUND,
            );
        }

        $body         = json_decode($request->getContent(), true);
        $confirmation = new SyncConfirmation(
            confirmDeletions: $body['confirmDeletions'] ?? false,
            confirmTypeChanges: $body['confirmTypeChanges'] ?? false,
        );

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

        return new JsonResponse($result);
    }
}
