import { version } from '../package.json.mjs';
import { isTestPublicToken, createPersistentId, createAppSessionId, createEventId } from '../../core/src/utils/index.mjs';
import { EventLogger, DEFAULT_INTERVAL_DURATION_MS, DEFAULT_MAX_BATCH_SIZE } from '../../core/src/EventLogger.mjs';
import { baseFetchSDK, baseSubmitFormSDK, retriableFetchSDK } from '../../core/src/NetworkClient.mjs';

class NetworkClient {
    _publicToken;
    _subscriptionDataLayer;
    additionalTelemetryDataFn;
    eventLogger;
    baseURL;
    constructor(_publicToken, _subscriptionDataLayer, _liveAPIURL, _testAPIURL, additionalTelemetryDataFn){
        this._publicToken = _publicToken;
        this._subscriptionDataLayer = _subscriptionDataLayer;
        this.additionalTelemetryDataFn = additionalTelemetryDataFn;
        this.baseURL = _liveAPIURL;
        if (isTestPublicToken(_publicToken)) {
            this.baseURL = _testAPIURL;
        }
        this.eventLogger = new EventLogger({
            maxBatchSize: DEFAULT_MAX_BATCH_SIZE,
            intervalDurationMs: DEFAULT_INTERVAL_DURATION_MS,
            logEventURL: this.buildSDKUrl('/events')
        });
    }
    // @deprecated Use the new sessions.updateSession() method instead
    updateSessionToken = ()=>{
        return null;
    };
    logEvent({ name, details, error = {} }) {
        this.eventLogger.logEvent(this.createTelemetryBlob(), {
            public_token: this._publicToken,
            event_name: name,
            details: details,
            // Error fields
            error_code: error.error_code,
            error_description: error.error_description,
            http_status_code: error.http_status_code
        });
    }
    createTelemetryBlob() {
        return {
            event_id: createEventId(),
            // TODO: These should be persisted somewhere, not generated per request
            app_session_id: createAppSessionId(),
            persistent_id: createPersistentId(),
            client_sent_at: new Date().toISOString(),
            timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
            // Logged in data
            // This gets passed into the constructor from StytchClient or StytchB2BClient
            // We pass in the user & session id when the Consumer SDK is being used and member & session id
            // when the B2B SDK is being used.
            // Why don't we generate this from the session_token in the auth header?
            // - We don't want to tie analytics ingest to session validation. There's no need to put
            //   that kind of pressure on API, and ingest could be moved to somewhere that doesn't
            //   have the ability to validate tokens
            // - For bulk event batches, we want to keep track of whether or not a user was logged
            //   in at each event. If we have 10 events, the user logs in at event 5, then they'll have
            //   a token when they log the batch, but we want to know that they were not logged in for the
            //   first 4 events
            ...this.additionalTelemetryDataFn(),
            // Versioning
            app: {
                identifier: window.location.hostname
            },
            sdk: {
                // TODO: Pull these from package.json when there is a package
                // eslint-disable-next-line lingui/no-unlocalized-strings
                identifier: 'Stytch.js Javascript SDK',
                version: version
            }
        };
    }
    async fetchSDK({ url, body, method }) {
        const sessionToken = this._subscriptionDataLayer.readSessionCookie().session_token;
        const basicAuthHeader = 'Basic ' + window.btoa(this._publicToken + ':' + (sessionToken || this._publicToken));
        const xSDKClientHeader = window.btoa(JSON.stringify(this.createTelemetryBlob()));
        const xSDKParentHostHeader = window.location.origin;
        return baseFetchSDK({
            basicAuthHeader,
            body,
            finalURL: this.buildSDKUrl(url),
            method,
            xSDKClientHeader,
            xSDKParentHostHeader
        });
    }
    async submitFormSDK({ url, body, method }) {
        const sessionToken = this._subscriptionDataLayer.readSessionCookie().session_token;
        const basicAuthHeader = 'Basic ' + window.btoa(this._publicToken + ':' + (sessionToken || this._publicToken));
        const xSDKClientHeader = window.btoa(JSON.stringify(this.createTelemetryBlob()));
        const xSDKParentHostHeader = window.location.origin;
        return baseSubmitFormSDK({
            basicAuthHeader,
            body,
            finalURL: this.buildSDKUrl(url),
            method,
            xSDKClientHeader,
            xSDKParentHostHeader
        });
    }
    async retriableFetchSDK({ url, body, method, retryCallback }) {
        const sessionToken = this._subscriptionDataLayer.readSessionCookie().session_token;
        const basicAuthHeader = 'Basic ' + window.btoa(this._publicToken + ':' + (sessionToken || this._publicToken));
        const xSDKClientHeader = window.btoa(JSON.stringify(this.createTelemetryBlob()));
        const xSDKParentHostHeader = window.location.origin;
        return retriableFetchSDK({
            basicAuthHeader,
            body,
            finalURL: this.buildSDKUrl(url),
            method,
            xSDKClientHeader,
            xSDKParentHostHeader,
            retryCallback
        });
    }
    buildSDKUrl(url) {
        // eslint-disable-next-line lingui/no-unlocalized-strings
        return `${this.baseURL}/sdk/v1${url}`;
    }
}

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