import { isTestPublicToken } from '../../utils/index.mjs';
import { validateInDev } from '../../utils/dev.mjs';
import { logger } from '../../utils/logger.mjs';

class HeadlessB2BSSOClient {
    _networkClient;
    _subscriptionService;
    _pkceManager;
    _dynamicConfig;
    _config;
    dfpProtectedAuth;
    authenticate;
    constructor(_networkClient, _subscriptionService, _pkceManager, _dynamicConfig, _config, dfpProtectedAuth){
        this._networkClient = _networkClient;
        this._subscriptionService = _subscriptionService;
        this._pkceManager = _pkceManager;
        this._dynamicConfig = _dynamicConfig;
        this._config = _config;
        this.dfpProtectedAuth = dfpProtectedAuth;
        this.authenticate = this._subscriptionService.withUpdateSession(async (options)=>{
            validateInDev('stytch.sso.authenticate', options, {
                sso_token: 'string',
                session_duration_minutes: 'number',
                locale: 'optionalString'
            });
            const keyPair = await this._pkceManager.getPKPair();
            if (!keyPair) {
                logger.warn('No code verifier found in local storage for SSO flow.\n' + 'Consider using stytch.sso.start() to add PKCE to your SSO flows for added security.\n' + 'See https://stytch.com/docs/oauth#guides_pkce for more information.');
            }
            const { dfp_telemetry_id, captcha_token } = await this.dfpProtectedAuth.getDFPTelemetryIDAndCaptcha();
            const resp = await this._networkClient.retriableFetchSDK({
                url: '/b2b/sso/authenticate',
                method: 'POST',
                body: {
                    pkce_code_verifier: keyPair?.code_verifier,
                    ...options,
                    dfp_telemetry_id,
                    captcha_token,
                    intermediate_session_token: this._subscriptionService.getIntermediateSessionToken() || undefined
                },
                retryCallback: this.dfpProtectedAuth.retryWithCaptchaAndDFP
            });
            this._pkceManager.clearPKPair();
            return resp;
        });
    }
    async getBaseApiUrl() {
        // Our TestAPIURL and LiveAPIURL should have the HTTPS protocol already attached
        // Don't add it twice!
        if (isTestPublicToken(this._config.publicToken)) {
            return this._config.testAPIURL;
        }
        return this._config.liveAPIURL;
    }
    async start({ connection_id, login_redirect_url, signup_redirect_url }) {
        const { pkceRequiredForSso } = await this._dynamicConfig;
        const baseURL = await this.getBaseApiUrl();
        const startUrl = new URL(`${baseURL}/v1/public/sso/start`);
        startUrl.searchParams.set('public_token', this._config.publicToken);
        startUrl.searchParams.set('connection_id', connection_id);
        if (pkceRequiredForSso) {
            const keyPair = await this._pkceManager.startPKCETransaction();
            startUrl.searchParams.set('pkce_code_challenge', keyPair.code_challenge);
        } else {
            this._pkceManager.clearPKPair();
        }
        if (login_redirect_url) startUrl.searchParams.set('login_redirect_url', login_redirect_url);
        if (signup_redirect_url) startUrl.searchParams.set('signup_redirect_url', signup_redirect_url);
        this.navigate(startUrl);
    }
    // Public so it can be mocked in tests
    navigate(url) {
        window.location.href = url.toString();
    }
    async getConnections() {
        return await this._networkClient.fetchSDK({
            url: '/b2b/sso',
            method: 'GET'
        });
    }
    async discoverConnections(emailAddress) {
        return await this._networkClient.fetchSDK({
            url: `/b2b/sso/discovery/connections?email_address=${encodeURIComponent(emailAddress)}`,
            method: 'GET'
        });
    }
    async deleteConnection(connectionId) {
        return this._networkClient.fetchSDK({
            url: `/b2b/sso/${connectionId}`,
            method: 'DELETE'
        });
    }
    saml = {
        createConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: '/b2b/sso/saml',
                method: 'POST',
                body: data
            });
        },
        updateConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/saml/${data.connection_id}`,
                method: 'PUT',
                body: data
            });
        },
        updateConnectionByURL: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/saml/${data.connection_id}/url`,
                method: 'PUT',
                body: data
            });
        },
        deleteVerificationCertificate: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/saml/${data.connection_id}/verification_certificates/${data.certificate_id}`,
                method: 'DELETE'
            });
        },
        deleteEncryptionPrivateKey: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/saml/${data.connection_id}/encryption_private_key/${data.private_key_id}`,
                method: 'DELETE'
            });
        }
    };
    oidc = {
        createConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: '/b2b/sso/oidc',
                method: 'POST',
                body: data
            });
        },
        updateConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/oidc/${data.connection_id}`,
                method: 'PUT',
                body: data
            });
        }
    };
    external = {
        createConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: '/b2b/sso/external',
                method: 'POST',
                body: data
            });
        },
        updateConnection: async (data)=>{
            return await this._networkClient.fetchSDK({
                url: `/b2b/sso/external/${data.connection_id}`,
                method: 'PUT',
                body: data
            });
        }
    };
}

export { HeadlessB2BSSOClient };
//# sourceMappingURL=HeadlessB2BSSOClient.mjs.map
