<?php

declare(strict_types=1);

namespace App\Module\Sites\Application\Service;

use App\Module\Core\Domain\Entity\User;
use App\Module\Sites\Domain\Entity\Site;
use App\Module\Sites\SitesModule;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

use function in_array;

/**
 * Resout le site courant de l'utilisateur authentifie pour les besoins de
 * l'outillage opt-in "site-aware" (ticket 4 module Sites).
 *
 * Consomme par :
 *  - SiteScopedQueryExtension : filtrage automatique des collections API.
 *  - SiteAwareInjectionProcessor : injection automatique sur POST/PATCH.
 *
 * Retourne `null` dans trois cas distincts (chacun volontairement
 * silencieux pour que les extensions/processor deviennent no-op sans
 * erreur visible) :
 *  1. Le module Sites est desactive dans `config/modules.php`.
 *  2. Aucun user n'est authentifie (appel depuis un endpoint public).
 *  3. L'user authentifie n'a pas de `currentSite` positionne (cas rare
 *     grace a la garde `UserRbacProcessor::ensureCurrentSiteConsistency`).
 *
 * Le flag `sitesActive` est calcule UNE FOIS au boot du service pour
 * eviter un `require` a chaque resolution.
 */
final class CurrentSiteProvider implements CurrentSiteProviderInterface
{
    private readonly bool $sitesActive;

    public function __construct(
        private readonly Security $security,
        #[Autowire(param: 'kernel.project_dir')]
        string $projectDir,
    ) {
        // Lit config/modules.php (tableau de FQCN) et verifie la presence
        // de SitesModule::class. Pattern aligne sur ModulesProvider.
        $configPath    = $projectDir.'/config/modules.php';
        $moduleClasses = file_exists($configPath) ? require $configPath : [];

        $this->sitesActive = in_array(SitesModule::class, $moduleClasses, true);
    }

    /**
     * Retourne le site courant de l'utilisateur authentifie, ou null si
     * l'une des 3 conditions de desactivation est remplie (cf. docblock
     * de classe).
     */
    public function get(): ?Site
    {
        if (!$this->sitesActive) {
            return null;
        }

        $user = $this->security->getUser();
        if (!$user instanceof User) {
            return null;
        }

        return $user->getCurrentSite();
    }
}
