<?php
declare(strict_types=1);
namespace PpPhp\Generated\SocialAuth;

final class SocialAuthManager
{
    public function __construct(private array $config) {}
    public function enabledProviders(string $intent): array
    {
        if (empty($this->config['enabled']) || empty($this->config[$intent === 'register' ? 'allow_registration' : 'allow_login'])) return [];
        return array_keys(array_filter((array)($this->config['providers']??[]),static fn($p)=>!empty($p['enabled'])));
    }
    public function begin(string $provider, string $intent): string
    {
        if (!in_array($provider,$this->enabledProviders($intent),true)) throw new \RuntimeException('This social provider is not enabled.');
        $state=bin2hex(random_bytes(24)); $nonce=bin2hex(random_bytes(24)); $verifier=rtrim(strtr(base64_encode(random_bytes(48)),'+/','-_'),'=');
        $_SESSION['pp_social_auth'][$state]=['provider'=>$provider,'intent'=>$intent,'nonce'=>$nonce,'verifier'=>$verifier,'created_at'=>time()];
        return $this->provider($provider)->authorizationUrl(compact('state','nonce','verifier','intent'));
    }
    public function complete(string $provider, array $request): array
    {
        $state=(string)($request['state']??''); $t=(array)($_SESSION['pp_social_auth'][$state]??[]); unset($_SESSION['pp_social_auth'][$state]);
        if ($state==='' || !$t || !hash_equals((string)($t['provider']??''),$provider) || time()-(int)($t['created_at']??0)>600) throw new \RuntimeException('The social sign-in request expired or failed state validation.');
        $identity=$this->provider($provider)->identity($request,$t); $identity['intent']=$t['intent']??'login'; return $identity;
    }
    private function provider(string $id): ProviderInterface
    {
        $cfg=(array)($this->config['providers'][$id]??[]);
        return match($id){'google'=>new GoogleProvider($cfg),'facebook'=>new FacebookProvider($cfg),'apple'=>new AppleProvider($cfg),'microsoft'=>new MicrosoftProvider($cfg),'github'=>new GitHubProvider($cfg),'linkedin'=>new LinkedInProvider($cfg),default=>throw new \RuntimeException('Unknown social provider.')};
    }
}
