<?php

declare(strict_types=1);

namespace App\Module\Commercial\Infrastructure\ApiPlatform\Serializer;

use ApiPlatform\State\SerializerContextBuilderInterface;
use App\Module\Commercial\Domain\Entity\Client;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
use Symfony\Component\HttpFoundation\Request;

/**
 * Decore le context builder de serialisation d'API Platform pour ajouter
 * DYNAMIQUEMENT le groupe de lecture `client:read:accounting` sur les ressources
 * Client, uniquement si l'utilisateur courant a la permission
 * `commercial.clients.accounting.view` (cf. spec-back M1 § 2.7 / § 4.1 / § 4.2).
 *
 * Pourquoi un context builder et pas le Provider : un Provider retourne des
 * donnees mais ne peut pas influencer les groupes de serialisation. Le contexte
 * de normalisation est construit ici, en amont du serializer — c'est le point
 * d'extension idiomatique d'API Platform pour conditionner un groupe selon
 * l'utilisateur. Realise l'intention « ajout conditionnel du groupe accounting »
 * de la spec.
 *
 * S'applique aux operations de LECTURE (normalization) sur Client : liste ET
 * detail. Sans la permission, les champs comptables (siren, accountNumber,
 * tvaMode, nTva, paymentDelay, paymentType, bank) ne sont jamais serialises.
 */
#[AsDecorator('api_platform.serializer.context_builder')]
final readonly class ClientReadGroupContextBuilder implements SerializerContextBuilderInterface
{
    public function __construct(
        #[AutowireDecorated]
        private SerializerContextBuilderInterface $decorated,
        private Security $security,
    ) {}

    public function createFromRequest(Request $request, bool $normalization, ?array $extractedAttributes = null): array
    {
        $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);

        // Uniquement en lecture, sur la ressource Client, avec la permission.
        if (!$normalization) {
            return $context;
        }

        if (Client::class !== ($context['resource_class'] ?? null)) {
            return $context;
        }

        if (!$this->security->isGranted('commercial.clients.accounting.view')) {
            return $context;
        }

        $groups = $context['groups'] ?? [];
        if (!in_array('client:read:accounting', $groups, true)) {
            $groups[] = 'client:read:accounting';
        }
        $context['groups'] = $groups;

        return $context;
    }
}
