security:
    # Hash des mots de passe
    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'

    # Provider pour charger les utilisateurs depuis la base de données
    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        # API MoodleV5 avec authentification mixte (clé API OU session)
        # Utilisé par SAM (Suivi Apprenants Moodle)
        # stateless: true évite la migration de session (session_regenerate_id) qui provoquerait
        # une condition de course avec les requêtes parallèles (Turbo frame + fetch Stimulus).
        api_moodlev5:
            pattern: ^/api/moodlev5/
            stateless: true
            provider: app_user_provider
            custom_authenticators:
                - App\Service\Security\MixedAuthenticator

        # API Badges — session-based, retourne 401 (JSON) au lieu de rediriger vers /login
        api_badges:
            pattern: ^/api/badges/
            stateless: true
            provider: app_user_provider
            custom_authenticators:
                - App\Security\SessionAuthenticator
            entry_point: App\Security\JsonAuthenticationEntryPoint

        # API Daily Reward — session-based, retourne 401 (JSON) au lieu de rediriger vers /login
        api_daily_reward:
            pattern: ^/api/daily-reward/
            stateless: true
            provider: app_user_provider
            custom_authenticators:
                - App\Security\SessionAuthenticator
            entry_point: App\Security\JsonAuthenticationEntryPoint

        # API REST legacy avec authentification par clé API
        # Exclut /api/settings/, /api/auth/, /api/sam/, /api/moodlev5/, /api/slidia/, /api/badges/ et /api/daily-reward/ qui utilisent la session via main
        api:
            pattern: ^/api/(?!settings/|auth/|sam/|moodlev5/|slidia/|badges/|daily-reward/)
            stateless: true
            provider: app_user_provider
            custom_authenticators:
                - App\Service\Security\ApiKeyAuthenticator

        main:
            lazy: true
            provider: app_user_provider
            user_checker: App\Security\UserChecker

            # Authenticator SSO Google
            custom_authenticators:
                - App\Security\GoogleAuthenticator

            # Configuration du formulaire de connexion
            form_login:
                login_path: app_login
                check_path: app_login
                default_target_path: app_dashboard
                enable_csrf: true

            # Configuration de la déconnexion
            logout:
                path: app_logout
                target: app_landing

            remember_me:
                secret: '%kernel.secret%'
                lifetime: 2592000 # 30 jours en secondes
                path: /

    # Contrôle d'accès
    # Toutes les pages nécessitent une authentification sauf landing page, login, register et reset password
    access_control:
        # API REST - protégée par clé API
        - { path: ^/api/, roles: ROLE_USER }
        # Pages publiques
        - { path: ^/$, roles: PUBLIC_ACCESS }
        - { path: ^/outils/, roles: PUBLIC_ACCESS }
        - { path: ^/login, roles: PUBLIC_ACCESS }
        - { path: ^/register, roles: PUBLIC_ACCESS }
        # Lien de parrainage — visité par des visiteurs anonymes avant inscription
        - { path: ^/r/, roles: PUBLIC_ACCESS }
        # Lien d'invitation d'un commercial — même public que /r/ : la personne
        # invitée n'a par définition pas encore de compte.
        - { path: ^/invitation/, roles: PUBLIC_ACCESS }
        - { path: ^/parrainage/confirmer/, roles: PUBLIC_ACCESS }
        - { path: ^/verify-email, roles: PUBLIC_ACCESS }
        - { path: ^/verify-new-email, roles: PUBLIC_ACCESS }
        - { path: ^/complete-registration, roles: PUBLIC_ACCESS }
        - { path: ^/connect/google, roles: PUBLIC_ACCESS }
        - { path: ^/forgot-password, roles: PUBLIC_ACCESS }
        - { path: ^/reset-password, roles: PUBLIC_ACCESS }
        # Webhook Stripe — sécurisé par signature HMAC (pas besoin de session)
        - { path: ^/webhook/stripe, roles: PUBLIC_ACCESS }
        - { path: ^/contact, roles: PUBLIC_ACCESS }
        - { path: ^/cgv, roles: PUBLIC_ACCESS }
        - { path: ^/mentions-legales, roles: PUBLIC_ACCESS }
        - { path: ^/politique-securite, roles: PUBLIC_ACCESS }
        - { path: ^/welcome, roles: PUBLIC_ACCESS }
        # Partage public d'un contenu Slidia/Scormia/Serenia — le visiteur n'a
        # par définition pas de compte. Le secret est le jeton, pas la session.
        #
        # ATTENTION : le slash final est indispensable. Une règle « ^/p »
        # ouvrirait au public /pixia, /promptly, /parrainage, /podcast et
        # /politique-securite.
        #
        # ATTENTION (2) : le segment « /p/ » de tête est tout aussi indispensable.
        # Ces chemins portent désormais le NOM DE L'OUTIL, donc ressemblent aux
        # préfixes des outils AUTHENTIFIÉS (/slidia, /scormia, /serenia). Une
        # règle « simplifiée » en ^/slidia/ ouvrirait l'éditeur entier aux
        # anonymes. Ces trois chemins sont recopiés à la main dans
        # PublicShareResponseListener::PUBLIC_PATH_PREFIXES : les deux listes
        # doivent rester identiques (verrouillé par
        # PublicShareResponseListenerTest::testLesPrefixesDuReplisSontExactementLesReglesAccessControl).
        - { path: ^/p/slidia/, roles: PUBLIC_ACCESS }
        - { path: ^/p/scormia/, roles: PUBLIC_ACCESS }
        - { path: ^/p/serenia/, roles: PUBLIC_ACCESS }
        - { path: ^/, roles: ROLE_USER }

    # Hiérarchie des rôles
    role_hierarchy:
        ROLE_ADMIN: [ROLE_COMPANY_MANAGER, ROLE_COMMERCIAL]
        ROLE_COMMERCIAL: ROLE_USER
        ROLE_COMPANY_MANAGER: ROLE_USER