<?php

namespace App\Controller\Api;

use App\Dto\SnipPostRequest;
use App\Entity\Snip;
use App\Entity\User;
use App\Repository\SnipRepository;
use App\Security\Voter\SnipVoter;
use App\Service\SnipContent\SnipContentService;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
use Symfony\Component\Routing\Attribute\Route;

class ApiController extends AbstractApiController
{
    #[Route('/me', methods: ['GET'])]
    public function me(): Response
    {
        /** @var User $user */
        $user = $this->getUser();

        return $this->successResponse([
            'id' => $user->getId(),
            'name' => $user->getName(),
            'email' => $user->getEmail(),
            'apiKey' => $user->getApiKey(),
        ]);
    }

    #[Route('/snip/{snip}', methods: ['GET'])]
    public function getSnip(Snip $snip): Response
    {
        $this->denyAccessUnlessGranted(SnipVoter::VIEW, $snip);

        return $this->successResponse([
            'id' => $snip->id,
            'content' => $snip->getActiveText(),
            'createdBy' => [
                'id' => $snip->createdBy->getId(),
                'name' => $snip->createdBy->getName(),
            ],
        ]);
    }

    #[Route('/snip/{snip}', methods: ['POST'])]
    public function postSnip(
        Snip                                 $snip,
        #[MapRequestPayload] SnipPostRequest $request,
        SnipContentService                   $cs,
        SnipRepository                       $repo,
        ObjectMapperInterface                $mapper,
    ): Response
    {
        $this->denyAccessUnlessGranted(SnipVoter::EDIT, $snip);

        if (!($snip->activeVersion === $snip->getLatestVersion())) {
            return $this->errorResponse('Snip is not the latest version');
        }

        $mapper->map($request, $snip);
        $repo->save($snip);
        if ($request->content !== null) {
            $cs->update($snip, $request->content, $request->contentName);
        }

        return $this->successResponse([
            'id' => $snip->id,
            'name' => $snip->name,
            'content' => $snip->getActiveText(),
            'createdBy' => [
                'id' => $snip->createdBy->getId(),
                'name' => $snip->createdBy->getName(),
            ],
        ]);
    }
}
