<?php

declare(strict_types=1);

namespace App\Shared\Infrastructure\ApiPlatform\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Shared\Domain\Contract\UserInterface;
use App\Shared\Domain\Module\ModuleRegistry;
use App\Shared\Domain\Sidebar\SidebarFilter;
use App\Shared\Infrastructure\ApiPlatform\Resource\SidebarResource;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

final readonly class SidebarProvider implements ProviderInterface
{
    public function __construct(
        #[Autowire('%kernel.project_dir%')]
        private string $projectDir,
        private Security $security,
    ) {}

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): SidebarResource
    {
        /** @var list<class-string> $moduleClasses */
        $moduleClasses = require $this->projectDir.'/config/modules.php';

        /** @var list<array{label:string, icon:string, roles?:list<string>, items: list<array{label:string, to:string, icon:string, module?:string, roles?:list<string>}>}> $sidebar */
        $sidebar = require $this->projectDir.'/config/sidebar.php';

        $user  = $this->security->getUser();
        $roles = null !== $user ? $user->getRoles() : [];

        // RBAC fin : permissions effectives du contrat. ROLE_ADMIN bypasse tout (Décision 1) :
        // on lui injecte le catalogue complet des permissions déclarées pour satisfaire les gates.
        if (in_array('ROLE_ADMIN', $roles, true)) {
            $permissions = array_column(ModuleRegistry::permissions($moduleClasses), 'code');
        } else {
            $permissions = $user instanceof UserInterface ? $user->getEffectivePermissions() : [];
        }

        $filtered = SidebarFilter::filter($sidebar, ModuleRegistry::ids($moduleClasses), array_values($roles), $permissions);

        $dto                 = new SidebarResource();
        $dto->sections       = $filtered['sections'];
        $dto->disabledRoutes = $filtered['disabledRoutes'];

        return $dto;
    }
}
