<?php

namespace MintyPHP\Service\Auth;

use MintyPHP\App\AppContainer;
use MintyPHP\App\Module\Contracts\SessionProvider;
use MintyPHP\App\Module\ModuleClassResolver;
use MintyPHP\App\Module\ModuleRegistry;
use MintyPHP\Http\SessionStoreInterface;
use MintyPHP\Service\User\UserTenantContextService;

class AuthSessionTenantContextService
{
    public function __construct(
        private readonly UserTenantContextService $userTenantContextService,
        private readonly SessionStoreInterface $sessionStore,
        private readonly AppContainer $container
    ) {
    }

    public function hydrateForUser(int $userId): void
    {
        if ($userId <= 0) {
            return;
        }

        $availableTenants = $this->userTenantContextService->getAvailableTenants($userId);
        $this->sessionStore->set('available_tenants', $availableTenants);

        if (!$availableTenants) {
            $this->sessionStore->set('no_active_tenant', true);
            $this->sessionStore->remove('current_tenant');
            return;
        }

        $this->sessionStore->set('no_active_tenant', false);

        // If the DB has no preferred tenant stored, fall back to the first available one.
        $currentTenant = $this->userTenantContextService->getCurrentTenant($userId);
        if (!$currentTenant) {
            $currentTenant = $availableTenants[0];
        }

        if ($currentTenant) {
            $this->sessionStore->set('current_tenant', $currentTenant);
        }

        $user = $this->sessionStore->get('user', []);
        $userRecord = is_array($user) ? $user : [];
        foreach ($this->moduleSessionProviders() as $provider) {
            $provider->populate($userRecord, $this->container);
        }
    }

    public function clearModuleSessionData(): void
    {
        foreach ($this->moduleSessionProviders() as $provider) {
            $provider->clear($this->container);
        }
    }

    /**
     * @return list<SessionProvider>
     */
    private function moduleSessionProviders(): array
    {
        $providers = [];
        try {
            $registry = $this->container->get(ModuleRegistry::class);
            if (!$registry instanceof ModuleRegistry) {
                return [];
            }
            foreach ($registry->getSessionProviders() as $providerClass) {
                $provider = ModuleClassResolver::resolve($this->container, $providerClass);
                if ($provider instanceof SessionProvider) {
                    $providers[] = $provider;
                }
            }
        } catch (\Throwable) {
            return [];
        }

        return $providers;
    }
}
